s3m-maplibre 0.4.4 → 0.4.5

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 S3MMapLibre=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},
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=[],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()}};function xi(e,t=1e-4){t=Math.max(t,2**-52);let n={},r=e.getIndex(),i=e.getAttribute(`position`),a=r?r.count:i.count,o=0,s=Object.keys(e.attributes),c={},l={},u=[],d=[`getX`,`getY`,`getZ`,`getW`],f=[`setX`,`setY`,`setZ`,`setW`];for(let t=0,n=s.length;t<n;t++){let n=s[t],r=e.attributes[n];c[n]=new r.constructor(new r.array.constructor(r.count*r.itemSize),r.itemSize,r.normalized);let i=e.morphAttributes[n];i&&(l[n]||(l[n]=[]),i.forEach((e,t)=>{let r=new e.array.constructor(e.count*e.itemSize);l[n][t]=new e.constructor(r,e.itemSize,e.normalized)}))}let p=t*.5,m=10**Math.log10(1/t),h=p*m;for(let t=0;t<a;t++){let i=r?r.getX(t):t,a=``;for(let t=0,n=s.length;t<n;t++){let n=s[t],r=e.getAttribute(n),o=r.itemSize;for(let e=0;e<o;e++)a+=`${~~(r[d[e]](i)*m+h)},`}if(a in n)u.push(n[a]);else{for(let t=0,n=s.length;t<n;t++){let n=s[t],r=e.getAttribute(n),a=e.morphAttributes[n],u=r.itemSize,p=c[n],m=l[n];for(let e=0;e<u;e++){let t=d[e],n=f[e];if(p[n](o,r[t](i)),a)for(let e=0,r=a.length;e<r;e++)m[e][n](o,a[e][t](i))}}n[a]=o,u.push(o),o++}}let g=e.clone();for(let t in e.attributes){let e=c[t];if(g.setAttribute(t,new e.constructor(e.array.slice(0,o*e.itemSize),e.itemSize,e.normalized)),t in l)for(let e=0;e<l[t].length;e++){let n=l[t][e];g.morphAttributes[t][e]=new n.constructor(n.array.slice(0,o*n.itemSize),n.itemSize,n.normalized)}}return g.setIndex(u),g}Wr();var Si=2;function Ci(e){return e===Q.SOLID?`solid`:e===Q.HEIGHT?`height`:`vertex`}var wi=`
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() {
@@ -370,7 +370,7 @@ var S3MMapLibre=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},
370
370
  gl_Position = projectionMatrix * viewMatrix * world;
371
371
  gl_PointSize = uPointSize;
372
372
  }
373
- `,Ti=`
373
+ `,wi=`
374
374
  uniform vec3 uColorA;
375
375
  uniform vec3 uColorB;
376
376
  uniform float uHeightMin;
@@ -381,13 +381,13 @@ var S3MMapLibre=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},
381
381
  float h = clamp( ( vWorldZ - uHeightMin ) / max( uHeightMax - uHeightMin, 0.001 ), 0.0, 1.0 );
382
382
  gl_FragColor = vec4( mix( uColorA, uColorB, h ), uOpacity );
383
383
  }
384
- `,Ei=`
384
+ `,Ti=`
385
385
  uniform vec3 uSelColor;
386
386
  uniform float uOpacity;
387
387
  void main() {
388
388
  gl_FragColor = vec4( uSelColor, uOpacity );
389
389
  }
390
- `;function Di(e,n,r){let i;return i=e===`height`?new t.ShaderMaterial({uniforms:{uColorA:r.uColorA,uColorB:r.uColorB,uHeightMin:r.uHeightMin,uHeightMax:r.uHeightMax,uPointSize:{value:Si},uOpacity:{value:n.opacity??1}},vertexShader:wi,fragmentShader:Ti,transparent:(n.opacity??1)<.999,depthWrite:(n.opacity??1)>=.999}):e===`selected`?new t.ShaderMaterial({uniforms:{uSelColor:r.uSelColor,uPointSize:{value:Si},uOpacity:{value:n.opacity??1}},vertexShader:wi,fragmentShader:Ei,transparent:(n.opacity??1)<.999,depthWrite:(n.opacity??1)>=.999}):e===`solid`?new t.PointsMaterial({size:Si,sizeAttenuation:!1,color:new t.Color(n.colorA),transparent:(n.opacity??1)<.999,opacity:n.opacity??1,depthWrite:(n.opacity??1)>=.999}):new t.PointsMaterial({size:Si,sizeAttenuation:!1,vertexColors:!0,transparent:(n.opacity??1)<.999,opacity:n.opacity??1,depthWrite:(n.opacity??1)>=.999}),i.userData.pcOwned=!0,i}function Oi(e,t,n,r=!1){let i=e.userData,a=r?`selected`:Ci(t.mode);if(i.pcKind!==a){let r=e.material;e.material=Di(a,t,n),r&&r.userData?.pcOwned&&r.dispose(),i.pcKind=a,i.pcTransparent=void 0}else a===`solid`&&e.material.color?.set(t.colorA);let o=Math.min(1,Math.max(.05,t.opacity??1)),s=o<.999,c=t.depthWrite!==!1,l=e.material;l.transparent=s,l.opacity=o,l.depthWrite=!s||c,l.uniforms?.uOpacity&&(l.uniforms.uOpacity.value=o),i.pcTransparent!==s&&(i.pcTransparent=s,l.needsUpdate=!0)}function ki(e){let t=Array.isArray(e)?e[0]:e;return!!t&&t.userData?.pcOwned===!0}var Ai=`
390
+ `;function Ei(e,n,r){let i;return i=e===`height`?new t.ShaderMaterial({uniforms:{uColorA:r.uColorA,uColorB:r.uColorB,uHeightMin:r.uHeightMin,uHeightMax:r.uHeightMax,uPointSize:{value:xi},uOpacity:{value:n.opacity??1}},vertexShader:Ci,fragmentShader:wi,transparent:(n.opacity??1)<.999,depthWrite:(n.opacity??1)>=.999}):e===`selected`?new t.ShaderMaterial({uniforms:{uSelColor:r.uSelColor,uPointSize:{value:xi},uOpacity:{value:n.opacity??1}},vertexShader:Ci,fragmentShader:Ti,transparent:(n.opacity??1)<.999,depthWrite:(n.opacity??1)>=.999}):e===`solid`?new t.PointsMaterial({size:xi,sizeAttenuation:!1,color:new t.Color(n.colorA),transparent:(n.opacity??1)<.999,opacity:n.opacity??1,depthWrite:(n.opacity??1)>=.999}):new t.PointsMaterial({size:xi,sizeAttenuation:!1,vertexColors:!0,transparent:(n.opacity??1)<.999,opacity:n.opacity??1,depthWrite:(n.opacity??1)>=.999}),i.userData.pcOwned=!0,i}function Di(e,t,n,r=!1){let i=e.userData,a=r?`selected`:Si(t.mode);if(i.pcKind!==a){let r=e.material;e.material=Ei(a,t,n),r&&r.userData?.pcOwned&&r.dispose(),i.pcKind=a,i.pcTransparent=void 0}else a===`solid`&&e.material.color?.set(t.colorA);let o=Math.min(1,Math.max(.05,t.opacity??1)),s=o<.999,c=t.depthWrite!==!1,l=e.material;l.transparent=s,l.opacity=o,l.depthWrite=!s||c,l.uniforms?.uOpacity&&(l.uniforms.uOpacity.value=o),i.pcTransparent!==s&&(i.pcTransparent=s,l.needsUpdate=!0)}function Oi(e){let t=Array.isArray(e)?e[0]:e;return!!t&&t.userData?.pcOwned===!0}var ki=`
391
391
  attribute float aBatchId;
392
392
  #ifdef USE_INSTANCING
393
393
  // 实例化:单体粒度在实例上,顶点属性里没有可用的 batchId
@@ -443,7 +443,7 @@ var S3MMapLibre=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},
443
443
  // 跟显示尺寸(2px)不匹配,点云会很难点中。对 Mesh 图元这行被忽略。
444
444
  gl_PointSize = 2.0;
445
445
  }
446
- `,ji=`
446
+ `,Ai=`
447
447
  uniform float uObjectId;
448
448
  varying float vBatch;
449
449
  void main() {
@@ -456,7 +456,7 @@ var S3MMapLibre=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},
456
456
  floor( b / 256.0 ) / 255.0
457
457
  );
458
458
  }
459
- `,Mi=(()=>{let e=new t.DataTexture(new Float32Array([-1,-1,-1,0,0,0,0,0]),1,2,t.RGBAFormat,t.FloatType);return e.minFilter=t.NearestFilter,e.magFilter=t.NearestFilter,e.needsUpdate=!0,e})();function Ni(e){return new t.ShaderMaterial({uniforms:{uObjectId:{value:e},uBatchTex:{value:Mi},uBatchTexWidth:{value:1},uBatchTexActive:{value:0},uSelBatch:{value:-1},uSelWhole:{value:0},uSelElevation:{value:0}},vertexShader:Ai,fragmentShader:ji,side:t.DoubleSide,depthTest:!0,depthWrite:!0,toneMapped:!1})}function Pi(e){return e.isPoints===!0}var Fi=class{constructor(e,t={}){h(this,`renderer`,void 0),h(this,`size`,void 0),h(this,`target`,null),h(this,`buf`,new Uint8Array(4)),this.renderer=e,this.size=Math.max(1,Math.floor(t.size??1))}_ensureTarget(e){return this.target&&this.target.width===e&&this.target.height===e||(this.target?.dispose(),this.target=new t.WebGLRenderTarget(e,e,{minFilter:t.NearestFilter,magFilter:t.NearestFilter,format:t.RGBAFormat,type:t.UnsignedByteType,depthBuffer:!0,stencilBuffer:!1}),this.target.texture.colorSpace=t.LinearSRGBColorSpace),this.target}pick(e,n,r,i){let a=this.renderer,o=a.domElement,s=o.width,c=o.height;if(!s||!c)return null;let l=Math.floor(r/o.clientWidth*s),u=Math.floor(i/o.clientHeight*c);if(l<0||u<0||l>=s||u>=c)return null;let d=this._ensureTarget(this.size),f=c-1-u,p=Math.floor(this.size/2),m=Math.floor(this.size/2);d.viewport.set(p-l,m-f,s,c);let h=a.getRenderTarget(),g=a.getViewport(new t.Vector4),_=a.toneMapping,v=a.outputColorSpace,y=a.autoClear,b=a.getClearColor(new t.Color),x=a.getClearAlpha(),S=[],C=new Set;e.traverseVisible(e=>{let t=e;if(!t.isMesh&&!Pi(t))return;let n=t.userData;if(n.pickId===void 0)return;n.pickMaterial||(n.pickMaterial=Ni(n.pickId)),t.isInstancedMesh&&C.add(n.pickId);let r=t.material,i=n.pickMaterial,a=Array.isArray(r)?r[0]:r,o=a?.userData?.uBatchTex;o?(i.uniforms.uBatchTex.value=o.value,i.uniforms.uBatchTexWidth.value=a?.userData?.uBatchTexWidth?.value??1,i.uniforms.uBatchTexActive.value=a?.userData?.uBatchTexActive?.value??0):(i.uniforms.uBatchTex.value=Mi,i.uniforms.uBatchTexWidth.value=1,i.uniforms.uBatchTexActive.value=0),i.uniforms.uSelBatch.value=a?.userData?.uSelBatch?.value??-1,i.uniforms.uSelWhole.value=a?.userData?.uSelWhole?.value??0,i.uniforms.uSelElevation.value=a?.uniforms?.uSelElevation?.value??0,S.push([t,r]),t.material=i});let w=[];e.traverseVisible(e=>{let t=e;(t.isMesh||Pi(t))&&t.userData.pickId===void 0&&(w.push(t),t.visible=!1)});let T=null;try{a.resetState(),a.setRenderTarget(d),a.toneMapping=t.NoToneMapping,a.outputColorSpace=t.LinearSRGBColorSpace,a.autoClear=!0,a.setClearColor(0,0),a.clear(),a.render(e,n),a.readRenderTargetPixels(d,p,m,1,1,this.buf);let r=this.buf[0],i=this.buf[1],o=this.buf[2],s=this.buf[3],c=r+i*256-1,l=o+s*256-1;c>=0&&(T=C.has(c)?{objectId:c,batchId:-1,instanceIndex:Math.max(0,l)}:{objectId:c,batchId:l})}finally{for(let[e,t]of S)e.material=t;for(let e of w)e.visible=!0;a.setRenderTarget(h),a.setViewport(g),a.toneMapping=_,a.outputColorSpace=v,a.autoClear=y,a.setClearColor(b,x),a.resetState()}return T}dispose(){this.target?.dispose(),this.target=null}};function Ii(){return{uResolution:{value:new t.Vector2(1,1)},uDpr:{value:1}}}var Li=`
459
+ `,ji=(()=>{let e=new t.DataTexture(new Float32Array([-1,-1,-1,0,0,0,0,0]),1,2,t.RGBAFormat,t.FloatType);return e.minFilter=t.NearestFilter,e.magFilter=t.NearestFilter,e.needsUpdate=!0,e})();function Mi(e){return new t.ShaderMaterial({uniforms:{uObjectId:{value:e},uBatchTex:{value:ji},uBatchTexWidth:{value:1},uBatchTexActive:{value:0},uSelBatch:{value:-1},uSelWhole:{value:0},uSelElevation:{value:0}},vertexShader:ki,fragmentShader:Ai,side:t.DoubleSide,depthTest:!0,depthWrite:!0,toneMapped:!1})}function Ni(e){return e.isPoints===!0}var Pi=class{constructor(e,t={}){h(this,`renderer`,void 0),h(this,`size`,void 0),h(this,`target`,null),h(this,`buf`,new Uint8Array(4)),this.renderer=e,this.size=Math.max(1,Math.floor(t.size??1))}_ensureTarget(e){return this.target&&this.target.width===e&&this.target.height===e||(this.target?.dispose(),this.target=new t.WebGLRenderTarget(e,e,{minFilter:t.NearestFilter,magFilter:t.NearestFilter,format:t.RGBAFormat,type:t.UnsignedByteType,depthBuffer:!0,stencilBuffer:!1}),this.target.texture.colorSpace=t.LinearSRGBColorSpace),this.target}pick(e,n,r,i){let a=this.renderer,o=a.domElement,s=o.width,c=o.height;if(!s||!c)return null;let l=Math.floor(r/o.clientWidth*s),u=Math.floor(i/o.clientHeight*c);if(l<0||u<0||l>=s||u>=c)return null;let d=this._ensureTarget(this.size),f=c-1-u,p=Math.floor(this.size/2),m=Math.floor(this.size/2);d.viewport.set(p-l,m-f,s,c);let h=a.getRenderTarget(),g=a.getViewport(new t.Vector4),_=a.toneMapping,v=a.outputColorSpace,y=a.autoClear,b=a.getClearColor(new t.Color),x=a.getClearAlpha(),S=[],C=new Set;e.traverseVisible(e=>{let t=e;if(!t.isMesh&&!Ni(t))return;let n=t.userData;if(n.pickId===void 0)return;n.pickMaterial||(n.pickMaterial=Mi(n.pickId)),t.isInstancedMesh&&C.add(n.pickId);let r=t.material,i=n.pickMaterial,a=Array.isArray(r)?r[0]:r,o=a?.userData?.uBatchTex;o?(i.uniforms.uBatchTex.value=o.value,i.uniforms.uBatchTexWidth.value=a?.userData?.uBatchTexWidth?.value??1,i.uniforms.uBatchTexActive.value=a?.userData?.uBatchTexActive?.value??0):(i.uniforms.uBatchTex.value=ji,i.uniforms.uBatchTexWidth.value=1,i.uniforms.uBatchTexActive.value=0),i.uniforms.uSelBatch.value=a?.userData?.uSelBatch?.value??-1,i.uniforms.uSelWhole.value=a?.userData?.uSelWhole?.value??0,i.uniforms.uSelElevation.value=a?.uniforms?.uSelElevation?.value??0,S.push([t,r]),t.material=i});let w=[];e.traverseVisible(e=>{let t=e;(t.isMesh||Ni(t))&&t.userData.pickId===void 0&&(w.push(t),t.visible=!1)});let T=null;try{a.resetState(),a.setRenderTarget(d),a.toneMapping=t.NoToneMapping,a.outputColorSpace=t.LinearSRGBColorSpace,a.autoClear=!0,a.setClearColor(0,0),a.clear(),a.render(e,n),a.readRenderTargetPixels(d,p,m,1,1,this.buf);let r=this.buf[0],i=this.buf[1],o=this.buf[2],s=this.buf[3],c=r+i*256-1,l=o+s*256-1;c>=0&&(T=C.has(c)?{objectId:c,batchId:-1,instanceIndex:Math.max(0,l)}:{objectId:c,batchId:l})}finally{for(let[e,t]of S)e.material=t;for(let e of w)e.visible=!0;a.setRenderTarget(h),a.setViewport(g),a.toneMapping=_,a.outputColorSpace=v,a.autoClear=y,a.setClearColor(b,x),a.resetState()}return T}dispose(){this.target?.dispose(),this.target=null}};function Fi(){return{uResolution:{value:new t.Vector2(1,1)},uDpr:{value:1}}}var Ii=`
460
460
  attribute vec3 aOther;
461
461
  attribute float aSide;
462
462
 
@@ -494,7 +494,7 @@ var S3MMapLibre=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},
494
494
 
495
495
  gl_Position = vec4( ndc * clipA.w, clipA.z, clipA.w );
496
496
  }
497
- `,Ri=`
497
+ `,Li=`
498
498
  uniform vec3 uColor;
499
499
  uniform float uOpacity;
500
500
 
@@ -502,7 +502,7 @@ var S3MMapLibre=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},
502
502
  if ( uOpacity <= 0.003 ) discard;
503
503
  gl_FragColor = vec4( uColor, uOpacity );
504
504
  }
505
- `;function zi(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:Li,fragmentShader:Ri,transparent:!0,depthWrite:!1,side:t.DoubleSide,polygonOffset:!0,polygonOffsetFactor:-2,polygonOffsetUnits:-2});return r.userData.isThickLine=!0,r}function Bi(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 Vi=6e4,Hi=100;function Ui(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]*Hi)},${Math.round(o[n]*Hi)},${Math.round(s[n]*Hi)}`,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>=Vi*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 Wi=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 Gi(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function Ki(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 qi(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 Ji(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 Yi=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=Ki(a,(t+n)/2),c=r+t*i,l=r+n*i;u.push({color:`#${o.getHexString()}`,label:`${Ji(c)} ~ ${Ji(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?qi(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=Gi(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}function Ui(e,n){let r=e.getAttribute(`position`);if(!r||r.count===0)return e;let i=1/Math.max(n,1e-9),a=new Map,o=[],s=new Int32Array(r.count);for(let e=0;e<r.count;e++){let t=r.getX(e),n=r.getY(e),c=r.getZ(e),l=`${Math.round(t*i)},${Math.round(n*i)},${Math.round(c*i)}`,u=a.get(l);u===void 0&&(u=o.length/3,o.push(t,n,c),a.set(l,u)),s[e]=u}let c=e.getIndex(),l=c?c.count:r.count,u=new Uint32Array(l);for(let e=0;e<l;e++)u[e]=s[c?c.getX(e):e];let d=new t.BufferGeometry;return d.setAttribute(`position`,new t.Float32BufferAttribute(o,3)),d.setIndex(new t.BufferAttribute(u,1)),d}var Wi=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 Gi(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function Ki(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 qi(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 Ji(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 Yi=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=Ki(a,(t+n)/2),c=r+t*i,l=r+n*i;u.push({color:`#${o.getHexString()}`,label:`${Ji(c)} ~ ${Ji(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?qi(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=Gi(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()}}},Xi=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 S3MMapLibre=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},
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 Zi=65534;function Qi(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function $i(e){return e.isPoints===!0}var ea=class e{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 Wi),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,`_creaseLines`,null),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 Xi(e.ground),this.scene||(this.scene=new t.Scene,this.scene.add(this.groundManager.group),this._addLights()),this._featureStyleManager=new Yi(()=>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=Ii(),this.edgeMaterial=zi(this.lineShared,{color:this.style.edgeColor,opacity:this.style.edgeOpacity??.45,width:this.style.edgeWidth??1.2}),this.selectionEdgeMaterial=zi(this.lineShared,{color:this.style.outlineColor??this.style.selectColor,opacity:1,width:this.style.outlineWidthPx??3}),this.setEdges(!!this.style.edges),this._fps.last=performance.now(),this._datasetQueue=this._normalizeDatasets(e),e.attributes&&(this.attributeQuery=new Ot(e.attributes))}_createRenderer(e,n){let r=new t.WebGLRenderer({canvas:e,context:n,antialias:!0});return r.autoClear=!1,r.setPixelRatio(1),r.toneMapping=t.ACESFilmicToneMapping,r.toneMappingExposure=1,r}mount(e,n){this.canvas=e,this.renderer=this._createRenderer(e,n),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 Fi(this.renderer),this._applyStyleUniforms();for(let e of this._datasetQueue)this.addDataset(e).catch(e=>this.onError(e));this._recomputeAnchors()}restoreContext(e){if(!this.canvas)console.warn(`[s3m] restoreContext 调用过早(尚未 mount),按首次挂载处理`);else{try{this.renderer?.dispose()}catch{}this.renderer=this._createRenderer(this.canvas,e),vr(this.renderer.capabilities.getMaxAnisotropy()),this.picker?.dispose(),this.picker=new Fi(this.renderer),this._requestRepaint()}}unmount(){for(let e of[...this.datasets.keys()])this.removeDataset(e);this.clearCreases(),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=Qi(t);r&&r.dispose(),ki(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=$i(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),!n&&!i&&this._datasetEdgesEnabled(t)&&!this._shouldSkipAutoEdges(o,t.name)&&this._ensureEdges(a),i)this._applyPointCloudStyle(r);else{let e=Qi(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=Qi(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),$i(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),Qi(t)?.dispose?.()}ki(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>Zi){for(let e=0;e<=Zi;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(),`edgeThreshold`in e&&this._edgesEnabled?this.setEdges(!0):`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($i(r.mesh)){this._applyPointCloudStyle(r.mesh);continue}let i=Qi(r.mesh);i&&(i.opacity=e,i.transparent=t,i.depthWrite=!t||n)}this._requestRepaint()}_applyPointCloudStyle(e,t=this._selectedMeshes.includes(e)){Oi(e,this.style,this.uniforms,t)}_applyPointCloudStyles(){for(let e of this._pickables.values())$i(e.mesh)&&this._applyPointCloudStyle(e.mesh);this._requestRepaint()}_applyShading(){let e=this.style.shading!==`smooth`;for(let t of this._pickables.values()){let n=Qi(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&&!$i(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()}async loadCreases(e){let n=await fetch(e);if(!n.ok)throw Error(`[s3m] 棱线缓存加载失败: ${n.status} ${e}`);let r=await n.arrayBuffer(),i=new Float32Array(r);if(i.length<6)return;let a=new t.BufferGeometry;a.setAttribute(`position`,new t.BufferAttribute(i,3));let o=this.style,s=new t.LineBasicMaterial({color:new t.Color(o.edgeColor),transparent:!0,opacity:Math.min(1,Math.max(0,o.edgeOpacity??.6))*Math.min(1,Math.max(.05,o.opacity??1)),depthWrite:!1}),c=new t.LineSegments(a,s);c.renderOrder=2,c.frustumCulled=!1,c.raycast=()=>{},this.clearCreases(),this._creaseLines=c,this.scene?.add(c),this._requestRepaint()}clearCreases(){this._creaseLines&&(this.scene?.remove(this._creaseLines),this._creaseLines.geometry.dispose(),this._creaseLines.material?.dispose?.(),this._creaseLines=null,this._requestRepaint())}_syncEdgeStyle(){let e=this.style,t=this.edgeMaterial.uniforms;if(t.uColor.value.set(e.edgeColor),t.uWidth.value=Math.max(.1,e.edgeWidth??1.5),t.uOpacity.value=Math.min(1,Math.max(0,e.edgeOpacity??.6))*Math.min(1,Math.max(.05,e.opacity??1)),this._creaseLines){let t=this._creaseLines.material;t.color.set(e.edgeColor),t.opacity=Math.min(1,Math.max(0,e.edgeOpacity??.6))*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??.6)*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)})}_datasetEdgesEnabled(e){let t=e.options?.enableEdges;return t===!0||t!==!1&&this._edgesEnabled}_shouldSkipAutoEdges(t,n){let r=`${t.skeletonName??``} ${n}`.toLowerCase();return e._EDGE_SKIP_KEYWORDS.some(e=>r.includes(e))}_ensureEdges(e){let n=e.userData;if(n.edges||n.nativeEdges||!e.geometry||this._shouldSkipAutoEdges(n,``))return;let r=e.geometry.getAttribute(`position`);if((e.geometry.index?.count??(r?r.count:0))>12e4)return;let i=xi(e.geometry,.005),a=this.style.edgeThreshold??55,o=new t.EdgesGeometry(i,a);i.dispose();let s=o.getAttribute(`position`),c=s?s.array:null;if(o.dispose(),!c||c.length<6)return;let l=new t.Mesh(Bi(c),this.edgeMaterial);l.renderOrder=2,l.frustumCulled=!1,l.raycast=()=>{},l.userData.isThickEdge=!0,n.edges=l,e.add(l)}_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($i(e)){this._applyPointCloudStyle(e,!1);continue}let t=Qi(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=Qi(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)$i(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=>!$i(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=Ui(r.geometry,a);if(o&&o.length>0){let n=new t.Mesh(Bi(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=Qi(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?Qi(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;let n=this.renderer.getContext();if(n&&typeof n.isContextLost==`function`&&n.isContextLost())return!1;this.flushOverrides();let r=this.canvas,i=this.sceneAnchor.meterInMercator;this._enuMatrix.set(i,0,0,this.sceneAnchor.x,0,-i,0,this.sceneAnchor.y,0,0,i,this.sceneAnchor.z,0,0,0,1);let a=new t.Matrix4().fromArray(e.mvp);a.multiply(this._enuMatrix),this.camera.projectionMatrix.copy(a),this.camera.projectionMatrixInverse.copy(a).invert();let o=e.cameraEnu;this.camera.position.set(o[0],o[1],o[2]),this.camera.matrixWorld.setPosition(o[0],o[1],o[2]),this.camera.matrixWorldInverse.copy(this.camera.matrixWorld).invert(),this.groundManager.update(this.camera);let s=!1;for(let t of this.datasets.values()){if(!t.visible||!t.tileset)continue;let n=[o[0]-t.offset[0],o[1]-t.offset[1],o[2]-t.offset[2]];t.tileset.update(n,e.fovRad,e.canvasHeight)&&(s=!0)}this.style.mode===Q.DYNAMIC&&(this.uniforms.uTime.value+=.016*(this.style.speed??1)),this._updateLights(),this._updateLineResolution(r),this.renderer.setViewport(0,0,r.width,r.height),this.renderer.resetState(),this.renderer.render(this.scene,this.camera),this._frame++;let c=performance.now();return c-this._fps.last>500&&(this._fps.value=Math.round(this._frame*1e3/(c-this._fps.last)),this._frame=0,this._fps.last=c),this.style.mode===Q.DYNAMIC||this.stats.loading>0||s}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()}};h(ea,`_EDGE_SKIP_KEYWORDS`,[`terrain`,`ground`,`vegetation`,`green`,`road`,`dem`,`绿地`,`道路`,`地面`,`地形`,`植被`,`铺装`]);var ta=1e-4;function na(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])>ta*r)return!1}return!0}function ra(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 ia(e,t){return t>0&&Math.abs(e.elements[5]*Math.tan(t/2)-1)<.001}function aa(e){if(!e||typeof e!=`object`)return null;let t=e;return t.defaultProjectionData?.projectionMatrix??t.projectionMatrix??null}function oa(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 sa(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 ca(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||!ia(i,n.fov))return null;let o=i.clone().invert().multiply(a);if(!na(i.clone().multiply(o),Array.from(e.mvp))||!ra(o)||!ia(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 la=.6435011087932844;function ua(e){let t=e,n=t?.transform?.worldCoordinateHelper??t?.transform?.projection?.worldCoordinateHelper??t?.painter?.transform?.worldCoordinateHelper??(typeof t?.getProjection==`function`?t.getProjection()?.worldCoordinateHelper:null)??null;return n&&typeof n.worldFromLngLat==`function`&&typeof n.lngLatFromWorld==`function`?n:null}function da(e){let t=ua(e);return t?{worldFromLngLat(e,n,r=0){let i=t.worldFromLngLat(e,n,r),a=0;if(typeof t.metersPerWorldUnit==`function`){let e=t.metersPerWorldUnit(i.x,i.y);Number.isFinite(e)&&e>0&&(a=1/e)}if(a===0){let o=t.worldFromLngLat(e,n,r+1),s=Math.abs((o.z??0)-(i.z??0));Math.sin(n*Math.PI/180),a=s>0?s:1/(2*Math.PI*6378137)/Math.cos(n*Math.PI/180)}return{x:i.x,y:i.y,z:i.z??r*a,meterInMercator:a,altitude:r}},lngLatFromWorld(e,n){let r=t.lngLatFromWorld(e,n);return Array.isArray(r)?[r[0],r[1]]:r&&typeof r.lng==`number`&&typeof r.lat==`number`?[r.lng,r.lat]:[0,0]}}:null}var fa=class{get map(){return this._map}set map(e){this._map=e,this.viewer.geo=e?da(e):null}_mapGl(){let e=this.map?.getCanvas?.();return e?e.getContext(`webgl2`)??e.getContext(`webgl`):null}constructor(e={}){h(this,`id`,void 0),h(this,`type`,`custom`),h(this,`renderingMode`,`3d`),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,`_map`,null),h(this,`viewer`,void 0),h(this,`_orthoWarned`,!1),h(this,`_projection`,`perspective`),h(this,`_onProjectionChange`,()=>{this.map&&(this.viewer.geo=da(this.map)),this.viewer.recomputeAnchors()}),h(this,`_contextLost`,!1),h(this,`_listenersAttached`,!1),h(this,`_onContextLost`,()=>{this._contextLost=!0}),h(this,`_onContextRestored`,()=>{this._contextLost=!1;let e=this.map;if(e){try{let t=e.getLayer,n=e.addLayer;if(!(typeof t==`function`&&t.call(e,this.id)))typeof n==`function`&&n.call(e,this);else{let e=this._mapGl();e&&this.viewer.restoreContext(e)}}catch(e){console.warn(`[s3m] WebGL 上下文恢复后重加图层失败,请手动 map.addLayer(layer)`,e)}e.triggerRepaint()}}),h(this,`_onClick`,e=>{if(!this.pickable)return;let t=this.pickFromEvent(e);t?(this.select(t),this.onPick(t)):this.select(null)}),this.id=e.id??`s3m`,this.options=e,this.pickable=e.pickable!==!1,this._projection=e.projection===`orthographic`?`orthographic`:`perspective`,this.onStats=e.onStats??(()=>{}),this.onReady=e.onReady??(()=>{}),this.onPick=e.onPick??(()=>{}),this.onError=e.onError??(e=>console.warn(`[s3m]`,e)),this.viewer=new ea({configUrl:e.configUrl,datasets:e.datasets,style:e.style,ground:e.ground,pickable:e.pickable,maxTiles:e.maxTiles,maxConcurrent:e.maxConcurrent,lodRangeScale:e.lodRangeScale,buildTile:e.buildTile,light:e.light,totalMaxTiles:e.totalMaxTiles,attributes:e.attributes,onRequestRepaint:()=>this.map?.triggerRepaint(),getBearing:()=>this.map?.getBearing?.()??0,onStats:e=>this.onStats(e),onReady:e=>this.onReady(e),onPick:e=>this.onPick(e),onError:e=>this.onError(e)})}onAdd(e,t){this.map=e,this.viewer.renderer?this.viewer.restoreContext(t):this.viewer.mount(e.getCanvas(),t),this._listenersAttached||(e.on(`click`,this._onClick),typeof e.on==`function`&&(e.on(`projectiontransition`,this._onProjectionChange),e.on(`webglcontextlost`,this._onContextLost),e.on(`webglcontextrestored`,this._onContextRestored)),this._listenersAttached=!0)}onRemove(){this.map?.off(`click`,this._onClick),typeof this.map?.off==`function`&&(this.map.off(`projectiontransition`,this._onProjectionChange),this.map.off(`webglcontextlost`,this._onContextLost),this.map.off(`webglcontextrestored`,this._onContextRestored)),this._listenersAttached=!1,this._contextLost=!1,this.viewer.unmount(),this.viewer.geo=null,this.map=null}_extractMatrix(e){if(Array.isArray(e)||e instanceof Float64Array||e instanceof Float32Array)return e;let t=e;return t?.defaultProjectionData?.mainMatrix??t?.modelViewProjectionMatrix??null}_applyOrtho(e,t){let{nearZ:n,farZ:r}=oa(e),i=aa(e);if(!i)return this._warnOrtho(`render() 输入里没有独立的投影矩阵(需要 MapLibre ≥ 5)`),null;let a=ca({projectionMatrix:i,mvp:t.elements,nearZ:n,farZ:r},{distance:this.map?.transform?.cameraToCenterDistance??0,fov:this._frameFov(e),aspect:this._canvasAspect()});return a?a.matrix:(this._warnOrtho(`拿到的投影矩阵与 MVP 不同源(反推结果不是仿射变换)`),null)}_warnOrtho(e){this._orthoWarned||(this._orthoWarned=!0,console.warn(`[s3m] 正交模式不可用:${e},本帧保持透视`))}_frameFov(e){return sa(e,this.map?.transform?.fovInRadians)??.6435011087932844}_canvasAspect(){let e=this.map?.getCanvas?.();return!e||!e.height?1:e.width/e.height}setProjection(e){let t=e===`orthographic`?`orthographic`:`perspective`;this._projection!==t&&(this._projection=t,this._orthoWarned=!1,this.map?.triggerRepaint())}get projection(){return this._projection}render(e,n){let r=this.map,i=this.viewer.sceneAnchor;if(!r||!i||this._contextLost)return;let a=this._extractMatrix(n);if(!a)return;let o=new t.Matrix4().fromArray(a);this._projection===`orthographic`&&(o=this._applyOrtho(n,o)??o);let s=r.getCanvas(),c=i.meterInMercator,l=[0,0,0];try{let e=r.getFreeCameraOptions?.()?.position;e&&(l=[(e.x-i.x)/c,-(e.y-i.y)/c,(e.z-i.z)/c])}catch{}this.viewer.renderFrame({mvp:o.elements,cameraEnu:l,fovRad:this._frameFov(n),canvasHeight:s.height})&&r.triggerRepaint()}pickFromEvent(e){let t=this.map?.getCanvas();if(!t)return null;let n=t.getBoundingClientRect(),r=e.originalEvent??e;return this.viewer.pick(r.clientX-n.left,r.clientY-n.top)}pick(e,t){return this.viewer.pick(e,t)}pickPosition(e,t){return this.viewer.pickPosition(e,t)}drillPick(e,t,n=10){return this.viewer.drillPick(e,t,n)}getRayAt(e,t){return this.viewer.getRayAt(e,t)}select(e,t={}){this.viewer.select(e,t)}getFeatureBounds(e){return this.viewer.getFeatureBounds(e)}flyToFeature(e,t){let n=this.viewer.getFeatureBounds(e);if(!n||!this.map)return!1;let r=this.map;return typeof r.fitBounds==`function`&&(r.fitBounds(n,{padding:50,maxZoom:19,duration:1200,...t}),!0)}addDataset(e){return this.viewer.addDataset(e)}removeDataset(e){this.viewer.removeDataset(e)}clearDatasets(){this.viewer.clearDatasets()}setDatasetVisible(e,t){this.viewer.setDatasetVisible(e,t)}getDatasetHeight(e){return this.viewer.getDatasetHeight(e)}setDatasetHeight(e,t){this.viewer.setDatasetHeight(e,t)}setDatasetAlign(e,t){this.viewer.setDatasetAlign(e,t)}_computeAlignOffset(e,t){return this.viewer.computeAlignOffset(e,t)}setLight(e){this.viewer.setLight(e)}getLight(){return this.viewer.getLight()}setOpacity(e){this.viewer.setOpacity(e)}setStyle(e={}){this.viewer.setStyle(e)}getStyle(){return this.viewer.getStyle()}setEdges(e){this.viewer.setEdges(e)}loadCreases(e){return this.viewer.loadCreases(e)}clearCreases(){this.viewer.clearCreases()}setFeatureStyle(e,t){this.viewer.setFeatureStyle(e,t)}setFeaturesStyle(e,t){this.viewer.setFeaturesStyle(e,t)}getFeatureStyle(e){return this.viewer.getFeatureStyle(e)}getFeatureStyles(){return this.viewer.getFeatureStyles()}removeFeatureStyle(e){this.viewer.removeFeatureStyle(e)}clearFeatureStyles(){this.viewer.clearFeatureStyles()}setAttributeSource(e){this.viewer.setAttributeSource(e)}getLoadedSmids(){return this.viewer.getLoadedSmids()}auditBatches(){return this.viewer.auditBatches()}getThematicField(){return this.viewer.getThematicField()}setThematicColors(e,t=`custom`){this.viewer.setThematicColors(e,t)}clearThematic(){this.viewer.clearThematic()}getFilterField(){return this.viewer.getFilterField()}filterByField(e){return this.viewer.filterByField(e)}clearFieldFilter(){this.viewer.clearFieldFilter()}getElevationField(){return this.viewer.getElevationField()}elevateByField(e){return this.viewer.elevateByField(e)}setThematicElevation(e,t=`custom`){this.viewer.setThematicElevation(e,t)}clearThematicElevation(){this.viewer.clearThematicElevation()}colorByField(e){return this.viewer.colorByField(e)}setFilter(e){this.viewer.setFilter(e)}getFilter(){return this.viewer.getFilter()}clearFilter(){this.viewer.clearFilter()}setGroundMode(e){this.viewer.setGroundMode(e)}setGroundOpacity(e){this.viewer.setGroundOpacity(e)}setExcavationBounds(e){this.viewer.setExcavationBounds(e)}setGroundOcclude(e){this.viewer.setGroundOcclude(e)}get groundManager(){return this.viewer.groundManager}getAllMeshes(){return this.viewer.getAllMeshes()}flushOverrides(){this.viewer.flushOverrides()}_applyOverridesToMesh(e){this.viewer._applyOverridesToMesh(e)}get lodRangeScale(){return this.viewer.lodRangeScale}setLodRangeScale(e,t){this.viewer.setLodRangeScale(e,t)}get renderer(){return this.viewer.renderer}get scene(){return this.viewer.scene}get camera(){return this.viewer.camera}get picker(){return this.viewer.picker}get uniforms(){return this.viewer.uniforms}get style(){return this.viewer.style}get outlineMaterial(){return this.viewer.outlineMaterial}get lineShared(){return this.viewer.lineShared}get edgeMaterial(){return this.viewer.edgeMaterial}get selectionEdgeMaterial(){return this.viewer.selectionEdgeMaterial}get datasets(){return this.viewer.datasets}get sceneAnchor(){return this.viewer.sceneAnchor}set sceneAnchor(e){this.viewer.sceneAnchor=e}get attributeQuery(){return this.viewer.attributeQuery}get fps(){return this.viewer.fps}get stats(){return this.viewer.stats}getBounds(){return this.viewer.getBounds()}dispose(){this.onRemove()}},pa=u({AttributeQuery:()=>Ot,BinaryReader:()=>g,DEFAULT_FLOOR_HEIGHT:()=>St,DEFAULT_FOV:()=>la,DEFAULT_STYLE:()=>Mr,DatasetManager:()=>Wi,EARTH_RADIUS:()=>kt,FeatureStyleManager:()=>Yi,GroundManager:()=>Xi,Picker:()=>Fi,PixelFormat:()=>X,S3MFormatError:()=>_t,S3MLayer:()=>fa,S3MTileset:()=>bi,S3MViewer:()=>ea,S3M_VERSION:()=>Ve,SELECT_MODE:()=>$,SELECT_MODE_LABELS:()=>jr,STYLE:()=>Q,STYLE_LABELS:()=>Ar,TextureCompress:()=>U,VertexTag:()=>R,VertexTagV3:()=>He,buildAttributes:()=>xt,buildFeatureEdgeSegments:()=>Ui,buildOrthoMVP:()=>ca,buildThickLineGeometry:()=>Bi,buildTileObjects:()=>si,createLineSharedUniforms:()=>Ii,createMapLibreGeoAdapter:()=>da,createOutlineMaterial:()=>kr,createSharedUniforms:()=>Dr,createStyledMaterial:()=>Or,createTexture:()=>Tr,createThickLineMaterial:()=>zi,default:()=>fa,dxtPixelFormatOf:()=>gn,extractFovRadians:()=>sa,extractNearFar:()=>oa,extractProjectionMatrix:()=>aa,extractWorldCoordinateHelper:()=>ua,isS3M1Buffer:()=>je,lngLatFromMercator:()=>jt,lngLatFromWorld:()=>Nt,measureSegments:()=>bt,mercatorFromLngLat:()=>At,parseS3M1:()=>Be,parseS3MB:()=>vt,resolveFeature:()=>V,resolveTextureKind:()=>hn,setMaxAnisotropy:()=>vr,worldFromLngLat:()=>Mt});Ct(),yn(),Z(),Wr(),ui();var ma=globalThis;return ma.THREE||(ma.THREE=t),ma.S3MMapLibre=pa,e.AttributeQuery=Ot,e.BinaryReader=g,e.DEFAULT_FLOOR_HEIGHT=St,e.DEFAULT_FOV=la,e.DEFAULT_STYLE=Mr,e.DatasetManager=Wi,e.EARTH_RADIUS=kt,e.FeatureStyleManager=Yi,e.GroundManager=Xi,e.Picker=Fi,e.PixelFormat=X,e.S3MFormatError=_t,e.S3MLayer=fa,e.default=fa,e.S3MTileset=bi,e.S3MViewer=ea,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=Ui,e.buildOrthoMVP=ca,e.buildThickLineGeometry=Bi,e.buildTileObjects=si,e.createLineSharedUniforms=Ii,e.createMapLibreGeoAdapter=da,e.createOutlineMaterial=kr,e.createSharedUniforms=Dr,e.createStyledMaterial=Or,e.createTexture=Tr,e.createThickLineMaterial=zi,e.dxtPixelFormatOf=gn,e.extractFovRadians=sa,e.extractNearFar=oa,e.extractProjectionMatrix=aa,e.extractWorldCoordinateHelper=ua,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 Zi=65534;function Qi(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function $i(e){return e.isPoints===!0}var ea=class e{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 Wi),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,`_creaseLines`,null),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 Xi(e.ground),this.scene||(this.scene=new t.Scene,this.scene.add(this.groundManager.group),this._addLights()),this._featureStyleManager=new Yi(()=>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.setEdges(!!this.style.edges),this._fps.last=performance.now(),this._datasetQueue=this._normalizeDatasets(e),e.attributes&&(this.attributeQuery=new Ot(e.attributes))}_createRenderer(e,n){let r=new t.WebGLRenderer({canvas:e,context:n,antialias:!0});return r.autoClear=!1,r.setPixelRatio(1),r.toneMapping=t.ACESFilmicToneMapping,r.toneMappingExposure=1,r}mount(e,n){this.canvas=e,this.renderer=this._createRenderer(e,n),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()}restoreContext(e){if(!this.canvas)console.warn(`[s3m] restoreContext 调用过早(尚未 mount),按首次挂载处理`);else{try{this.renderer?.dispose()}catch{}this.renderer=this._createRenderer(this.canvas,e),vr(this.renderer.capabilities.getMaxAnisotropy()),this.picker?.dispose(),this.picker=new Pi(this.renderer),this._requestRepaint()}}unmount(){for(let e of[...this.datasets.keys()])this.removeDataset(e);this.clearCreases(),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=Qi(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=$i(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),!n&&!i&&this._datasetEdgesEnabled(t)&&!this._shouldSkipAutoEdges(o,t.name)&&this._ensureEdges(a),i)this._applyPointCloudStyle(r);else{let e=Qi(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=Qi(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),$i(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),Qi(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>Zi){for(let e=0;e<=Zi;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(),`edgeThreshold`in e&&this._edgesEnabled?this.setEdges(!0):`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($i(r.mesh)){this._applyPointCloudStyle(r.mesh);continue}let i=Qi(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())$i(e.mesh)&&this._applyPointCloudStyle(e.mesh);this._requestRepaint()}_applyShading(){let e=this.style.shading!==`smooth`;for(let t of this._pickables.values()){let n=Qi(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&&!$i(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()}async loadCreases(e){let n=await fetch(e);if(!n.ok)throw Error(`[s3m] 棱线缓存加载失败: ${n.status} ${e}`);let r=await n.arrayBuffer(),i=new Float32Array(r);if(i.length<6)return;let a=new t.BufferGeometry;a.setAttribute(`position`,new t.BufferAttribute(i,3));let o=this.style,s=new t.LineBasicMaterial({color:new t.Color(o.edgeColor),transparent:!0,opacity:Math.min(1,Math.max(0,o.edgeOpacity??.6))*Math.min(1,Math.max(.05,o.opacity??1)),depthWrite:!1}),c=new t.LineSegments(a,s);c.renderOrder=2,c.frustumCulled=!1,c.raycast=()=>{},this.clearCreases(),this._creaseLines=c,this.scene?.add(c),this._requestRepaint()}clearCreases(){this._creaseLines&&(this.scene?.remove(this._creaseLines),this._creaseLines.geometry.dispose(),this._creaseLines.material?.dispose?.(),this._creaseLines=null,this._requestRepaint())}_syncEdgeStyle(){let e=this.style,t=this.edgeMaterial.uniforms;if(t.uColor.value.set(e.edgeColor),t.uWidth.value=Math.max(.1,e.edgeWidth??1.5),t.uOpacity.value=Math.min(1,Math.max(0,e.edgeOpacity??.6))*Math.min(1,Math.max(.05,e.opacity??1)),this._creaseLines){let t=this._creaseLines.material;t.color.set(e.edgeColor),t.opacity=Math.min(1,Math.max(0,e.edgeOpacity??.6))*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??.6)*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)})}_datasetEdgesEnabled(e){let t=e.options?.enableEdges;return t===!0||t!==!1&&this._edgesEnabled}_shouldSkipAutoEdges(t,n){let r=`${t.skeletonName??``} ${n}`.toLowerCase();return e._EDGE_SKIP_KEYWORDS.some(e=>r.includes(e))}_ensureEdges(e){let n=e.userData;if(n.edges||n.nativeEdges||!e.geometry||this._shouldSkipAutoEdges(n,``))return;let r=e.geometry.getAttribute(`position`);if((e.geometry.index?.count??(r?r.count:0))>12e4)return;let i=Ui(e.geometry,.005),a=this.style.edgeThreshold??55,o=new t.EdgesGeometry(i,a);i.dispose();let s=o.getAttribute(`position`),c=s?s.array:null;if(o.dispose(),!c||c.length<6)return;let l=new t.Mesh(zi(c),this.edgeMaterial);l.renderOrder=2,l.frustumCulled=!1,l.raycast=()=>{},l.userData.isThickEdge=!0,n.edges=l,e.add(l)}_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($i(e)){this._applyPointCloudStyle(e,!1);continue}let t=Qi(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=Qi(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)$i(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=>!$i(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=Qi(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?Qi(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;let n=this.renderer.getContext();if(n&&typeof n.isContextLost==`function`&&n.isContextLost())return!1;this.flushOverrides();let r=this.canvas,i=this.sceneAnchor.meterInMercator;this._enuMatrix.set(i,0,0,this.sceneAnchor.x,0,-i,0,this.sceneAnchor.y,0,0,i,this.sceneAnchor.z,0,0,0,1);let a=new t.Matrix4().fromArray(e.mvp);a.multiply(this._enuMatrix),this.camera.projectionMatrix.copy(a),this.camera.projectionMatrixInverse.copy(a).invert();let o=e.cameraEnu;this.camera.position.set(o[0],o[1],o[2]),this.camera.matrixWorld.setPosition(o[0],o[1],o[2]),this.camera.matrixWorldInverse.copy(this.camera.matrixWorld).invert(),this.groundManager.update(this.camera);let s=!1;for(let t of this.datasets.values()){if(!t.visible||!t.tileset)continue;let n=[o[0]-t.offset[0],o[1]-t.offset[1],o[2]-t.offset[2]];t.tileset.update(n,e.fovRad,e.canvasHeight)&&(s=!0)}this.style.mode===Q.DYNAMIC&&(this.uniforms.uTime.value+=.016*(this.style.speed??1)),this._updateLights(),this._updateLineResolution(r),this.renderer.setViewport(0,0,r.width,r.height),this.renderer.resetState(),this.renderer.render(this.scene,this.camera),this._frame++;let c=performance.now();return c-this._fps.last>500&&(this._fps.value=Math.round(this._frame*1e3/(c-this._fps.last)),this._frame=0,this._fps.last=c),this.style.mode===Q.DYNAMIC||this.stats.loading>0||s}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()}};h(ea,`_EDGE_SKIP_KEYWORDS`,[`terrain`,`ground`,`vegetation`,`green`,`road`,`dem`,`绿地`,`道路`,`地面`,`地形`,`植被`,`铺装`]);var ta=1e-4;function na(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])>ta*r)return!1}return!0}function ra(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 ia(e,t){return t>0&&Math.abs(e.elements[5]*Math.tan(t/2)-1)<.001}function aa(e){if(!e||typeof e!=`object`)return null;let t=e;return t.defaultProjectionData?.projectionMatrix??t.projectionMatrix??null}function oa(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 sa(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 ca(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||!ia(i,n.fov))return null;let o=i.clone().invert().multiply(a);if(!na(i.clone().multiply(o),Array.from(e.mvp))||!ra(o)||!ia(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 la=.6435011087932844;function ua(e){let t=e,n=t?.transform?.worldCoordinateHelper??t?.transform?.projection?.worldCoordinateHelper??t?.painter?.transform?.worldCoordinateHelper??(typeof t?.getProjection==`function`?t.getProjection()?.worldCoordinateHelper:null)??null;return n&&typeof n.worldFromLngLat==`function`&&typeof n.lngLatFromWorld==`function`?n:null}function da(e){let t=ua(e);return t?{worldFromLngLat(e,n,r=0){let i=t.worldFromLngLat(e,n,r),a=0;if(typeof t.metersPerWorldUnit==`function`){let e=t.metersPerWorldUnit(i.x,i.y);Number.isFinite(e)&&e>0&&(a=1/e)}if(a===0){let o=t.worldFromLngLat(e,n,r+1),s=Math.abs((o.z??0)-(i.z??0));Math.sin(n*Math.PI/180),a=s>0?s:1/(2*Math.PI*6378137)/Math.cos(n*Math.PI/180)}return{x:i.x,y:i.y,z:i.z??r*a,meterInMercator:a,altitude:r}},lngLatFromWorld(e,n){let r=t.lngLatFromWorld(e,n);return Array.isArray(r)?[r[0],r[1]]:r&&typeof r.lng==`number`&&typeof r.lat==`number`?[r.lng,r.lat]:[0,0]}}:null}var fa=class{get map(){return this._map}set map(e){this._map=e,this.viewer.geo=e?da(e):null}_mapGl(){let e=this.map?.getCanvas?.();return e?e.getContext(`webgl2`)??e.getContext(`webgl`):null}constructor(e={}){h(this,`id`,void 0),h(this,`type`,`custom`),h(this,`renderingMode`,`3d`),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,`_map`,null),h(this,`viewer`,void 0),h(this,`_orthoWarned`,!1),h(this,`_projection`,`perspective`),h(this,`_onProjectionChange`,()=>{this.map&&(this.viewer.geo=da(this.map)),this.viewer.recomputeAnchors()}),h(this,`_contextLost`,!1),h(this,`_listenersAttached`,!1),h(this,`_onContextLost`,()=>{this._contextLost=!0}),h(this,`_onContextRestored`,()=>{this._contextLost=!1;let e=this.map;if(e){try{let t=e.getLayer,n=e.addLayer;if(!(typeof t==`function`&&t.call(e,this.id)))typeof n==`function`&&n.call(e,this);else{let e=this._mapGl();e&&this.viewer.restoreContext(e)}}catch(e){console.warn(`[s3m] WebGL 上下文恢复后重加图层失败,请手动 map.addLayer(layer)`,e)}e.triggerRepaint()}}),h(this,`_onClick`,e=>{if(!this.pickable)return;let t=this.pickFromEvent(e);t?(this.select(t),this.onPick(t)):this.select(null)}),this.id=e.id??`s3m`,this.options=e,this.pickable=e.pickable!==!1,this._projection=e.projection===`orthographic`?`orthographic`:`perspective`,this.onStats=e.onStats??(()=>{}),this.onReady=e.onReady??(()=>{}),this.onPick=e.onPick??(()=>{}),this.onError=e.onError??(e=>console.warn(`[s3m]`,e)),this.viewer=new ea({configUrl:e.configUrl,datasets:e.datasets,style:e.style,ground:e.ground,pickable:e.pickable,maxTiles:e.maxTiles,maxConcurrent:e.maxConcurrent,lodRangeScale:e.lodRangeScale,buildTile:e.buildTile,light:e.light,totalMaxTiles:e.totalMaxTiles,attributes:e.attributes,onRequestRepaint:()=>this.map?.triggerRepaint(),getBearing:()=>this.map?.getBearing?.()??0,onStats:e=>this.onStats(e),onReady:e=>this.onReady(e),onPick:e=>this.onPick(e),onError:e=>this.onError(e)})}onAdd(e,t){this.map=e,this.viewer.renderer?this.viewer.restoreContext(t):this.viewer.mount(e.getCanvas(),t),this._listenersAttached||(e.on(`click`,this._onClick),typeof e.on==`function`&&(e.on(`projectiontransition`,this._onProjectionChange),e.on(`webglcontextlost`,this._onContextLost),e.on(`webglcontextrestored`,this._onContextRestored)),this._listenersAttached=!0)}onRemove(){this.map?.off(`click`,this._onClick),typeof this.map?.off==`function`&&(this.map.off(`projectiontransition`,this._onProjectionChange),this.map.off(`webglcontextlost`,this._onContextLost),this.map.off(`webglcontextrestored`,this._onContextRestored)),this._listenersAttached=!1,this._contextLost=!1,this.viewer.unmount(),this.viewer.geo=null,this.map=null}_extractMatrix(e){if(Array.isArray(e)||e instanceof Float64Array||e instanceof Float32Array)return e;let t=e;return t?.defaultProjectionData?.mainMatrix??t?.modelViewProjectionMatrix??null}_applyOrtho(e,t){let{nearZ:n,farZ:r}=oa(e),i=aa(e);if(!i)return this._warnOrtho(`render() 输入里没有独立的投影矩阵(需要 MapLibre ≥ 5)`),null;let a=ca({projectionMatrix:i,mvp:t.elements,nearZ:n,farZ:r},{distance:this.map?.transform?.cameraToCenterDistance??0,fov:this._frameFov(e),aspect:this._canvasAspect()});return a?a.matrix:(this._warnOrtho(`拿到的投影矩阵与 MVP 不同源(反推结果不是仿射变换)`),null)}_warnOrtho(e){this._orthoWarned||(this._orthoWarned=!0,console.warn(`[s3m] 正交模式不可用:${e},本帧保持透视`))}_frameFov(e){return sa(e,this.map?.transform?.fovInRadians)??.6435011087932844}_canvasAspect(){let e=this.map?.getCanvas?.();return!e||!e.height?1:e.width/e.height}setProjection(e){let t=e===`orthographic`?`orthographic`:`perspective`;this._projection!==t&&(this._projection=t,this._orthoWarned=!1,this.map?.triggerRepaint())}get projection(){return this._projection}render(e,n){let r=this.map,i=this.viewer.sceneAnchor;if(!r||!i||this._contextLost)return;let a=this._extractMatrix(n);if(!a)return;let o=new t.Matrix4().fromArray(a);this._projection===`orthographic`&&(o=this._applyOrtho(n,o)??o);let s=r.getCanvas(),c=i.meterInMercator,l=[0,0,0];try{let e=r.getFreeCameraOptions?.()?.position;e&&(l=[(e.x-i.x)/c,-(e.y-i.y)/c,(e.z-i.z)/c])}catch{}this.viewer.renderFrame({mvp:o.elements,cameraEnu:l,fovRad:this._frameFov(n),canvasHeight:s.height})&&r.triggerRepaint()}pickFromEvent(e){let t=this.map?.getCanvas();if(!t)return null;let n=t.getBoundingClientRect(),r=e.originalEvent??e;return this.viewer.pick(r.clientX-n.left,r.clientY-n.top)}pick(e,t){return this.viewer.pick(e,t)}pickPosition(e,t){return this.viewer.pickPosition(e,t)}drillPick(e,t,n=10){return this.viewer.drillPick(e,t,n)}getRayAt(e,t){return this.viewer.getRayAt(e,t)}select(e,t={}){this.viewer.select(e,t)}getFeatureBounds(e){return this.viewer.getFeatureBounds(e)}flyToFeature(e,t){let n=this.viewer.getFeatureBounds(e);if(!n||!this.map)return!1;let r=this.map;return typeof r.fitBounds==`function`&&(r.fitBounds(n,{padding:50,maxZoom:19,duration:1200,...t}),!0)}addDataset(e){return this.viewer.addDataset(e)}removeDataset(e){this.viewer.removeDataset(e)}clearDatasets(){this.viewer.clearDatasets()}setDatasetVisible(e,t){this.viewer.setDatasetVisible(e,t)}getDatasetHeight(e){return this.viewer.getDatasetHeight(e)}setDatasetHeight(e,t){this.viewer.setDatasetHeight(e,t)}setDatasetAlign(e,t){this.viewer.setDatasetAlign(e,t)}_computeAlignOffset(e,t){return this.viewer.computeAlignOffset(e,t)}setLight(e){this.viewer.setLight(e)}getLight(){return this.viewer.getLight()}setOpacity(e){this.viewer.setOpacity(e)}setStyle(e={}){this.viewer.setStyle(e)}getStyle(){return this.viewer.getStyle()}setEdges(e){this.viewer.setEdges(e)}loadCreases(e){return this.viewer.loadCreases(e)}clearCreases(){this.viewer.clearCreases()}setFeatureStyle(e,t){this.viewer.setFeatureStyle(e,t)}setFeaturesStyle(e,t){this.viewer.setFeaturesStyle(e,t)}getFeatureStyle(e){return this.viewer.getFeatureStyle(e)}getFeatureStyles(){return this.viewer.getFeatureStyles()}removeFeatureStyle(e){this.viewer.removeFeatureStyle(e)}clearFeatureStyles(){this.viewer.clearFeatureStyles()}setAttributeSource(e){this.viewer.setAttributeSource(e)}getLoadedSmids(){return this.viewer.getLoadedSmids()}auditBatches(){return this.viewer.auditBatches()}getThematicField(){return this.viewer.getThematicField()}setThematicColors(e,t=`custom`){this.viewer.setThematicColors(e,t)}clearThematic(){this.viewer.clearThematic()}getFilterField(){return this.viewer.getFilterField()}filterByField(e){return this.viewer.filterByField(e)}clearFieldFilter(){this.viewer.clearFieldFilter()}getElevationField(){return this.viewer.getElevationField()}elevateByField(e){return this.viewer.elevateByField(e)}setThematicElevation(e,t=`custom`){this.viewer.setThematicElevation(e,t)}clearThematicElevation(){this.viewer.clearThematicElevation()}colorByField(e){return this.viewer.colorByField(e)}setFilter(e){this.viewer.setFilter(e)}getFilter(){return this.viewer.getFilter()}clearFilter(){this.viewer.clearFilter()}setGroundMode(e){this.viewer.setGroundMode(e)}setGroundOpacity(e){this.viewer.setGroundOpacity(e)}setExcavationBounds(e){this.viewer.setExcavationBounds(e)}setGroundOcclude(e){this.viewer.setGroundOcclude(e)}get groundManager(){return this.viewer.groundManager}getAllMeshes(){return this.viewer.getAllMeshes()}flushOverrides(){this.viewer.flushOverrides()}_applyOverridesToMesh(e){this.viewer._applyOverridesToMesh(e)}get lodRangeScale(){return this.viewer.lodRangeScale}setLodRangeScale(e,t){this.viewer.setLodRangeScale(e,t)}get renderer(){return this.viewer.renderer}get scene(){return this.viewer.scene}get camera(){return this.viewer.camera}get picker(){return this.viewer.picker}get uniforms(){return this.viewer.uniforms}get style(){return this.viewer.style}get outlineMaterial(){return this.viewer.outlineMaterial}get lineShared(){return this.viewer.lineShared}get edgeMaterial(){return this.viewer.edgeMaterial}get selectionEdgeMaterial(){return this.viewer.selectionEdgeMaterial}get datasets(){return this.viewer.datasets}get sceneAnchor(){return this.viewer.sceneAnchor}set sceneAnchor(e){this.viewer.sceneAnchor=e}get attributeQuery(){return this.viewer.attributeQuery}get fps(){return this.viewer.fps}get stats(){return this.viewer.stats}getBounds(){return this.viewer.getBounds()}dispose(){this.onRemove()}},pa=u({AttributeQuery:()=>Ot,BinaryReader:()=>g,DEFAULT_FLOOR_HEIGHT:()=>St,DEFAULT_FOV:()=>la,DEFAULT_STYLE:()=>Mr,DatasetManager:()=>Wi,EARTH_RADIUS:()=>kt,FeatureStyleManager:()=>Yi,GroundManager:()=>Xi,Picker:()=>Pi,PixelFormat:()=>X,S3MFormatError:()=>_t,S3MLayer:()=>fa,S3MTileset:()=>bi,S3MViewer:()=>ea,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:()=>ca,buildThickLineGeometry:()=>zi,buildTileObjects:()=>si,createLineSharedUniforms:()=>Fi,createMapLibreGeoAdapter:()=>da,createOutlineMaterial:()=>kr,createSharedUniforms:()=>Dr,createStyledMaterial:()=>Or,createTexture:()=>Tr,createThickLineMaterial:()=>Ri,default:()=>fa,dxtPixelFormatOf:()=>gn,extractFovRadians:()=>sa,extractNearFar:()=>oa,extractProjectionMatrix:()=>aa,extractWorldCoordinateHelper:()=>ua,isS3M1Buffer:()=>je,lngLatFromMercator:()=>jt,lngLatFromWorld:()=>Nt,measureSegments:()=>bt,mercatorFromLngLat:()=>At,parseS3M1:()=>Be,parseS3MB:()=>vt,resolveFeature:()=>V,resolveTextureKind:()=>hn,setMaxAnisotropy:()=>vr,worldFromLngLat:()=>Mt});Ct(),yn(),Z(),Wr(),ui();var ma=globalThis;return ma.THREE||(ma.THREE=t),ma.S3MMapLibre=pa,e.AttributeQuery=Ot,e.BinaryReader=g,e.DEFAULT_FLOOR_HEIGHT=St,e.DEFAULT_FOV=la,e.DEFAULT_STYLE=Mr,e.DatasetManager=Wi,e.EARTH_RADIUS=kt,e.FeatureStyleManager=Yi,e.GroundManager=Xi,e.Picker=Pi,e.PixelFormat=X,e.S3MFormatError=_t,e.S3MLayer=fa,e.default=fa,e.S3MTileset=bi,e.S3MViewer=ea,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=ca,e.buildThickLineGeometry=zi,e.buildTileObjects=si,e.createLineSharedUniforms=Fi,e.createMapLibreGeoAdapter=da,e.createOutlineMaterial=kr,e.createSharedUniforms=Dr,e.createStyledMaterial=Or,e.createTexture=Tr,e.createThickLineMaterial=Ri,e.dxtPixelFormatOf=gn,e.extractFovRadians=sa,e.extractNearFar=oa,e.extractProjectionMatrix=aa,e.extractWorldCoordinateHelper=ua,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);
@@ -4195,7 +4195,7 @@ void main() {
4195
4195
  if ( vSel < 0.5 ) discard;
4196
4196
  gl_FragColor = vec4( uColor, 1.0 );
4197
4197
  }
4198
- `})),My=i({LINE_PRIMITIVE:()=>13,POINT_PRIMITIVE:()=>1,buildTileObjects:()=>Jy});function Ny(e){return e===13||e===2||e===3}function Py(e){return e===1}function Fy(){return Yy||(Yy=new dd({size:2,sizeAttenuation:!1,vertexColors:!0})),Yy}function Iy(e){return e===`u8`?1:e===`u16`?2:4}function Ly(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 Ry(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 zy(e){let{data:t,stride:n,offsetInBytes:r,dtype:i=`f32`}=e,a=e.components??e.comp??3,o=Iy(i),s=a*o,c=n??s,l=r??0,u=i===`u8`;if(c===s&&l===0){let e=Ly(i,t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength));return new G(e,a,u)}let d=Math.floor(t.byteLength/c),f=Ry(i,d*a),p=new DataView(t.buffer,t.byteOffset,t.byteLength);for(let e=0;e<d;e++){let t=e*c+l;for(let n=0;n<a;n++){let r=t+n*o;f[e*a+n]=i===`u8`?p.getUint8(r):i===`u16`?p.getUint16(r,!0):i===`u32`?p.getUint32(r,!0):p.getFloat32(r,!0)}}return new G(f,a,u)}function By(e){let{indices:t,indexType:n,indexCount:r}=e;if(!t||r===0)return null;let i=Math.floor(t.byteLength/r),a=i===4||i!==2&&(n===1||n===3),o=r*(a?4:2);if(o>t.byteLength)return null;let s=t.buffer.slice(t.byteOffset,t.byteOffset+o),c=a?new Uint32Array(s):new Uint16Array(s);return new G(c,1)}function Vy(e,t){let n=new Float32Array(t*3);if(!e)return n.fill(1),new G(n,3);let r=e.data,i=e.components??4,a=e.dtype===`u8`?1/255:1;for(let e=0;e<t;e++){let t=e*i;n[e*3]=(r[t]??255)*a,n[e*3+1]=(r[t+1]??255)*a,n[e*3+2]=(r[t+2]??255)*a}return new G(n,3)}function Hy(e){if(!e)return[];if(Array.isArray(e))return e;let t=e,n=t.materials??t.material;return Array.isArray(n)?n:[]}function Uy(e){return e?.material??e}function Wy(e){return e?.name??e?.id}function Gy(e){return(e?.textureStates??e?.textureunitstates??[]).map(e=>e?.textureunitstate??e).filter(e=>!!e)}function Ky(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 qy(e){let t=String(e?.cullMode??``).toUpperCase();return t===`CULL_BACK`||t===`BACKWARD`?0:t===`CULL_FRONT`?1:2}async function Jy(e,t={}){let n=t.uniforms??fy(),r=t.textureCache??new Map,i=new Ml,a=[],o=[],s={meshes:0,vertices:0,triangles:0,textures:0,instanced:0,edgeLines:0,skipped:[]},c=new Qu({color:new W(t.edgeColor??`#1f2937`),transparent:!0,opacity:.75,depthWrite:!1});i.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),i=r.get(e);if(i){let t=i.image;if((t?.width??0)*(t?.height??0)>=(n.width??0)*(n.height??0))continue;r.delete(e)}let{texture:a,decoded:c}=await cy(n);a?(r.set(e,a),o.push(e),s.textures++):s.skipped.push(`texture ${t} → ${c}`)}let u=Hy(e.materials),d=(e,t=!1)=>{let i=Uy(u.find(t=>Wy(Uy(t))===e)),a=Gy(i),o=a[0],s=o?r.get(l(Wy(o)??o.id??``))??null:null,c=a[1],d=globalThis.__S3M_NO_BAKE===!0,f=t&&c&&!d?r.get(l(Wy(c)??c.id??``))??null:null,p=o?.texmodmatrix??o?.matrix;if(s&&Array.isArray(p)&&p.length===16&&!Ky(p)&&(s=s.clone(),s.matrixAutoUpdate=!1,s.matrix.set(p[0],p[4],p[12],p[1],p[5],p[13],0,0,1)),s&&o?.addressmode){let e=o.addressmode.u,t=o.addressmode.v;(e!==void 0||t!==void 0)&&(s.matrixAutoUpdate&&(s=s.clone()),e!==void 0&&(s.wrapS=e===0?Ir:z),t!==void 0&&(s.wrapT=t===0?Ir:z))}let m=i?.diffuse??{r:1,g:1,b:1,a:1},h=i?.alphaMode,g=[o,c].some(e=>/\.water$/i.test(String(Wy(e)??e?.id??``))),_=h===`AM_BLEND`||(m.a??1)<.999||i?.transparentsorting===!0||g&&!s,v=typeof i?.shininess==`number`&&i.shininess>0?Math.max(.15,1-i.shininess/128):.95,y=s?.userData?.s3mHasAlpha?Math.max(i?.alphaCutoff??0,.01):0;return py({uniforms:n,map:s,color:g&&!s?Xy.clone():new W(m.r??1,m.g??1,m.b??1),side:qy(i),transparent:_,opacity:g&&!s?.86:m.a??1,roughness:g&&!s?.12:v,alphaTest:y,atlas:t&&!!s,secMap:f})},f=new Map,p=new Map;for(let[t,n]of Object.entries(e.geoPackage??{})){let r=n.vertexPackage,i=r.vertexAttributes.find(e=>e.semantic===`position`);if(!i){s.skipped.push(`${t} 无 position`);continue}let a=r.verticesCount||0,o={position:zy(i)},c=null,l=null;for(let e of r.vertexAttributes)e.divisor===void 0&&e.semantic!==`position`&&(e.semantic===`color`?c=e:e.semantic===`batchId`?l=e:e.semantic===`normal`?o.normal=zy(e):e.semantic===`uv`?o.uv=zy(e):e.semantic===`uv2`&&(o.uv1=zy(e)));o.aColor=Vy(c,a),o.aBatchId=l?zy(l):new G(new Float32Array(a).fill(-1),1);let u=e.atlasRects?.[t];if(u){o.aAtlasRect=new G(u.uv??new Float32Array(a*4),4);let e=o.uv1;u.uv2&&e?(o.aAtlasRect1=new G(u.uv2,4),o.aSecUv=e):(o.aAtlasRect1=new G(new Float32Array(a*4),4),o.aSecUv=o.uv??new G(new Float32Array(a*2),2))}let d=r.instanceIndex!==-1&&(r.instanceMode===16||r.instanceMode===17),m=n.indexPackages??[];m.length===0&&a>0&&(m=[{indexCount:0,indexType:0,useIndex:0,primitiveType:1,indices:null,passNames:[]}]),p.set(t,{indexPackages:m,instanced:d}),s.vertices+=a,m.forEach((e,n)=>{let r=new q;for(let[e,t]of Object.entries(o))r.setAttribute(e,t);let i=By(e);i?r.setIndex(i):r.setDrawRange(0,a),Ny(e.primitiveType)||Py(e.primitiveType)||r.getAttribute(`normal`)||r.computeVertexNormals(),r.computeBoundingBox(),r.computeBoundingSphere(),f.set(`${t}|${n}`,{geometry:r,pack:e})})}let m=new U,h=new Map,g=(e,t,n)=>{let r=0,i=0,a=!1,o=!1,s=!1,c=!1,l=!1,u=!1;for(let t of e){let e=t.cached.geometry,n=e.attributes.position?.count??0;r+=n,i+=e.index?e.index.count:n,e.attributes.normal&&(a=!0),e.attributes.uv&&(o=!0),e.attributes.uv1&&(s=!0),e.attributes.aColor&&(c=!0),e.attributes.aBatchId&&(l=!0),e.attributes.aAtlasRect&&(u=!0)}let d=new Float32Array(r*3),f=a?new Float32Array(r*3):null,p=o?new Float32Array(r*2):null,h=s?new Float32Array(r*2):null,g=c?new Float32Array(r*3):null,_=l?new Float32Array(r):null,v=u?new Float32Array(r*4):null,y=u?new Float32Array(r*4):null,b=u?new Float32Array(r*2):null,x=(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}},S=new(r>65535?Uint32Array:Uint16Array)(i),C=0,w=0,T=new H,E=new V,D=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&&a&&E.getNormalMatrix(r),t.geo.pickInfo)for(let e of Object.values(t.geo.pickInfo))typeof e.batchId==`number`&&e.batchId>=0&&D.set(e.batchId,t.geo);let o=e.attributes.position.array;for(let e=0;e<n;e++){let t=e*3,n=(C+e)*3;i?(T.set(o[t],o[t+1],o[t+2]).applyMatrix4(r),d[n]=T.x,d[n+1]=T.y,d[n+2]=T.z):(d[n]=o[t],d[n+1]=o[t+1],d[n+2]=o[t+2])}if(f){let t=e.attributes.normal;if(t){let e=t.array;for(let t=0;t<n;t++){let n=t*3,r=(C+t)*3;i?(T.set(e[n],e[n+1],e[n+2]).applyMatrix3(E).normalize(),f[r]=T.x,f[r+1]=T.y,f[r+2]=T.z):(f[r]=e[n],f[r+1]=e[n+1],f[r+2]=e[n+2])}}}if(p){let t=e.attributes.uv;if(t){let e=t.array;for(let t=0;t<n;t++)p[(C+t)*2]=e[t*2],p[(C+t)*2+1]=e[t*2+1]}}if(h){let t=e.attributes.uv1;if(t){let e=t.array;for(let t=0;t<n;t++)h[(C+t)*2]=e[t*2],h[(C+t)*2+1]=e[t*2+1]}}if(g){let t=e.attributes.aColor;if(t){let e=t.array;for(let t=0;t<n;t++)g[(C+t)*3]=e[t*3],g[(C+t)*3+1]=e[t*3+1],g[(C+t)*3+2]=e[t*3+2]}else for(let e=0;e<n;e++)g[(C+e)*3]=1,g[(C+e)*3+1]=1,g[(C+e)*3+2]=1}if(_){let t=e.attributes.aBatchId;if(t){let e=t.array;for(let t=0;t<n;t++)_[C+t]=e[t]}else for(let e=0;e<n;e++)_[C+e]=-1}if(v&&(x(v,e.attributes.aAtlasRect,4,n,C,(e,t)=>t.push(0,0,0,0)),x(y,e.attributes.aAtlasRect1,4,n,C,(e,t)=>t.push(0,0,0,0)),x(b,e.attributes.aSecUv,2,n,C)),e.index){let t=e.index.array,n=e.index.count;for(let e=0;e<n;e++)S[w+e]=t[e]+C;w+=n}else{for(let e=0;e<n;e++)S[w+e]=e+C;w+=n}C+=n}let O=new q;O.setAttribute(`position`,new G(d,3)),f&&O.setAttribute(`normal`,new G(f,3)),p&&O.setAttribute(`uv`,new G(p,2)),h&&O.setAttribute(`uv1`,new G(h,2)),g&&O.setAttribute(`aColor`,new G(g,3)),_&&O.setAttribute(`aBatchId`,new G(_,1)),v&&(O.setAttribute(`aAtlasRect`,new G(v,4)),O.setAttribute(`aAtlasRect1`,new G(y,4)),O.setAttribute(`aSecUv`,new G(b,2))),O.setIndex(new G(S,1)),O.computeBoundingBox(),O.computeBoundingSphere();let k=new dc(O,t);return k.userData.skeletonName=e[0].name,k.userData.geoRef=e[0].geo,k.userData.tileRef=n,k.userData.primitiveType=4,k.userData.isBatched=!0,k.userData.batchedCount=e.length,D.size>0&&(k.userData.geoByBatchId=D),k},_=(n,r,o,l)=>{let{geometry:u,pack:f}=n,h=d(f.passNames?.[0],!!u.getAttribute(`aAtlasRect`)),g,_=p.get(r),v=o.vertexPackage;if(Ny(f.primitiveType)){let e=new ld(u,c);return e.visible=t.edges===!0,e.renderOrder=2,e.raycast=()=>{},e.userData.isEdgeLines=!0,e.userData.skeletonName=r,l&&!l.equals(m)&&l.decompose(e.position,e.quaternion,e.scale),i.add(e),a.push(e),i.userData.hasNativeEdges=!0,s.edgeLines++,e}if(Py(f.primitiveType)){u.getAttribute(`color`)||u.setAttribute(`color`,u.getAttribute(`aColor`));let t=new gd(u,Fy());return t.userData.isPointCloud=!0,t.userData.skeletonName=r,t.userData.geoRef=o,t.userData.tileRef=e,t.userData.primitiveType=f.primitiveType,l&&!l.equals(m)&&l.decompose(t.position,t.quaternion,t.scale),i.add(t),a.push(t),s.meshes++,t}if(_?.instanced&&v.instanceBuffer&&v.instanceCount>0){if(!u.getAttribute(`aInstanceBatchId`)){let e=v.instanceBatchIds,t=e&&e.length===v.instanceCount?e.slice():new Float32Array(v.instanceCount).fill(-1);u.setAttribute(`aInstanceBatchId`,new Du(t,1));let n=new Float32Array(v.instanceCount);for(let e=0;e<n.length;e++)n[e]=e;u.setAttribute(`aInstanceIndex`,new Du(n,1))}let e=new Fu(u,h,v.instanceCount);e.instanceMatrix.setUsage(Ea);let t=new U,n=new W,r=v.instanceMode,i=new Float32Array(v.instanceBuffer.buffer,v.instanceBuffer.byteOffset,v.instanceCount*r);for(let a=0;a<v.instanceCount;a++){let o=a*r;if(t.set(i[o+0],i[o+1],i[o+2],i[o+3],i[o+4],i[o+5],i[o+6],i[o+7],i[o+8],i[o+9],i[o+10],i[o+11],0,0,0,1),e.setMatrixAt(a,t),r>=16){let t=i[o+12],r=i[o+13],s=i[o+14];Number.isFinite(t)&&Number.isFinite(r)&&Number.isFinite(s)&&(n.setRGB(t,r,s),e.setColorAt(a,n))}}e.instanceMatrix.needsUpdate=!0,e.instanceColor&&(e.instanceColor.needsUpdate=!0),e.frustumCulled=!1,s.instanced++,g=e}else g=new dc(u,h);return l&&!l.equals(m)&&l.decompose(g.position,g.quaternion,g.scale),g.userData.skeletonName=r,g.userData.geoRef=o,g.userData.tileRef=e,g.userData.primitiveType=f.primitiveType,i.add(g),a.push(g),s.meshes++,f.primitiveType===4&&(s.triangles+=(f.indexCount||0)/3),g},v=0;for(let n of e.groupNode?.pageLods??[])for(let r of n.geodes??[]){let n=r.matrix,i=n&&n.length===16?new U().fromArray(n):null;for(let n of r.skeletonNames??[]){let r=p.get(n);if(!r)continue;let a=e.geoPackage[n];if(!a)continue;let o=a.vertexPackage;for(let e=0;e<r.indexPackages.length;e++){let s=f.get(`${n}|${e}`);if(s){if(Ny(s.pack.primitiveType)||r.instanced&&o.instanceBuffer&&o.instanceCount>0)_(s,n,a,i),v++;else if(t.batching!==!1&&s.pack.primitiveType===4){let e=s.pack.passNames?.[0]??`__default__`,t=h.get(e);t||(t=[],h.set(e,t)),t.push({cached:s,name:n,geo:a,matrix:i}),v++}else _(s,n,a,i),v++}}}}if(v===0)for(let[n,r]of p){let i=e.geoPackage[n];if(!i)continue;let a=i.vertexPackage;for(let e=0;e<r.indexPackages.length;e++){let o=f.get(`${n}|${e}`);if(o){if(Ny(o.pack.primitiveType)||r.instanced&&a.instanceBuffer&&a.instanceCount>0)_(o,n,i,null);else if(t.batching!==!1&&o.pack.primitiveType===4){let e=o.pack.passNames?.[0]??`__default__`,t=h.get(e);t||(t=[],h.set(e,t)),t.push({cached:o,name:n,geo:i,matrix:null})}else _(o,n,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`),o=g(n,d(t===`__default__`?void 0:t,r),e);i.add(o),a.push(o),s.meshes++;for(let e of n)s.triangles+=(e.cached.pack.indexCount||0)/3}return i.children.length||s.skipped.push(`tile 无可用几何`),i.userData.textureKeys=o,{group:i,stats:s,objects:a,textureKeys:o}}var Yy,Xy,Zy=n((()=>{rh(),dy(),jy(),Yy=null,Xy=new W(1920611)}));function Qy(e){return e.slice(0,e.lastIndexOf(`/`)+1)}function $y(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 eb(e,t){if(!t)return null;try{return tb(new URL(t,e).href)}catch{return tb(`${Qy(e)}${t}`)}}function tb(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 nb=110540,rb=111320;function ib(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 ab(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?eb(Qy(e),n):tb(`${r[r.length-1]===`path`&&r[r.length-2]===`data`?`${r.join(`/`)}/${a}`:`${r.join(`/`)}/data/path/${a}`}/${n}`)}function ob(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=rb*Math.cos(i*Math.PI/180);n>1e-6&&(o=r+e/n,s=r+t/n,l=i+a/nb,c=i+u/nb)}}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 sb=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){X(this,`configUrl`,void 0),X(this,`config`,null),X(this,`_blockTileIndex`,null),X(this,`anchor`,{lon:0,lat:0,height:0}),X(this,`rootUrls`,[]),X(this,`nodes`,new Map),X(this,`failed`,new Set),X(this,`textureCache`,new Map),X(this,`maxImageCache`,void 0),X(this,`_textureRefs`,new Map),X(this,`_tileTextureKeys`,new Map),X(this,`pending`,new Set),X(this,`atlasLod`,void 0),X(this,`atlasLodCache`,new Map),X(this,`_groupCache`,new Map),X(this,`externalAtlasCache`,new Map),X(this,`leafRequestCache`,new Map),X(this,`_leafPending`,new Map),X(this,`atlasUpgraded`,new Set),X(this,`atlasUpgradeSkipped`,new Map),X(this,`stats`,{tiles:0,loading:0,failed:0,meshes:0,vertices:0,triangles:0,datasets:1}),X(this,`maxConcurrent`,void 0),X(this,`maxTiles`,void 0),X(this,`lodRangeScale`,void 0),X(this,`_onTile`,void 0),X(this,`_onTileRemoved`,void 0),X(this,`_onError`,void 0),X(this,`_onProgress`,void 0),X(this,`_maxRetries`,void 0),X(this,`_retryCount`,new Map),X(this,`_retryAt`,new Map),X(this,`_parentOf`,new Map),X(this,`_frame`,0),X(this,`_lodDbgOnce`,!1),X(this,`_permanentReported`,!1),X(this,`hardCap`,96),X(this,`isS3MV1`,!1),X(this,`_buildTile`,void 0),X(this,`_uniforms`,void 0),X(this,`_queue`,[]),X(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=$y(this.configUrl);let e=await fetch(this.configUrl);if(!e.ok)throw Error(`配置读取失败 ${e.status} ${this.configUrl}`);let t=ob(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=eb(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=eb(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=ib(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(()=>(Zy(),My));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=j_(n),a=!1,o=new Map,s=new Map,c=[];for(let[e,t]of Object.entries(r)){let n=V_(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=H_(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=ev(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)&&M_(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=eb(Qy(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 F_(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=eb(Qy(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 F_(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 U_(t);this._rememberGroups(n,e),o=e.names,a=e.tiles[r]??e.tiles[0]}else a=await qg(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?ab(e,t.childTile):eb(Qy(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?ab(e,f?.childTile):eb(Qy(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()}};function cb(e,t=1e-4){t=Math.max(t,2**-52);let n={},r=e.getIndex(),i=e.getAttribute(`position`),a=r?r.count:i.count,o=0,s=Object.keys(e.attributes),c={},l={},u=[],d=[`getX`,`getY`,`getZ`,`getW`],f=[`setX`,`setY`,`setZ`,`setW`];for(let t=0,n=s.length;t<n;t++){let n=s[t],r=e.attributes[n];c[n]=new r.constructor(new r.array.constructor(r.count*r.itemSize),r.itemSize,r.normalized);let i=e.morphAttributes[n];i&&(l[n]||(l[n]=[]),i.forEach((e,t)=>{let r=new e.array.constructor(e.count*e.itemSize);l[n][t]=new e.constructor(r,e.itemSize,e.normalized)}))}let p=t*.5,m=10**Math.log10(1/t),h=p*m;for(let t=0;t<a;t++){let i=r?r.getX(t):t,a=``;for(let t=0,n=s.length;t<n;t++){let n=s[t],r=e.getAttribute(n),o=r.itemSize;for(let e=0;e<o;e++)a+=`${~~(r[d[e]](i)*m+h)},`}if(a in n)u.push(n[a]);else{for(let t=0,n=s.length;t<n;t++){let n=s[t],r=e.getAttribute(n),a=e.morphAttributes[n],u=r.itemSize,p=c[n],m=l[n];for(let e=0;e<u;e++){let t=d[e],n=f[e];if(p[n](o,r[t](i)),a)for(let e=0,r=a.length;e<r;e++)m[e][n](o,a[e][t](i))}}n[a]=o,u.push(o),o++}}let g=e.clone();for(let t in e.attributes){let e=c[t];if(g.setAttribute(t,new e.constructor(e.array.slice(0,o*e.itemSize),e.itemSize,e.normalized)),t in l)for(let e=0;e<l[t].length;e++){let n=l[t][e];g.morphAttributes[t][e]=new n.constructor(n.array.slice(0,o*n.itemSize),n.itemSize,n.normalized)}}return g.setIndex(u),g}rh(),jy();var lb=2;function ub(e){return e===hy.SOLID?`solid`:e===hy.HEIGHT?`height`:`vertex`}var db=`
4198
+ `})),My=i({LINE_PRIMITIVE:()=>13,POINT_PRIMITIVE:()=>1,buildTileObjects:()=>Jy});function Ny(e){return e===13||e===2||e===3}function Py(e){return e===1}function Fy(){return Yy||(Yy=new dd({size:2,sizeAttenuation:!1,vertexColors:!0})),Yy}function Iy(e){return e===`u8`?1:e===`u16`?2:4}function Ly(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 Ry(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 zy(e){let{data:t,stride:n,offsetInBytes:r,dtype:i=`f32`}=e,a=e.components??e.comp??3,o=Iy(i),s=a*o,c=n??s,l=r??0,u=i===`u8`;if(c===s&&l===0){let e=Ly(i,t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength));return new G(e,a,u)}let d=Math.floor(t.byteLength/c),f=Ry(i,d*a),p=new DataView(t.buffer,t.byteOffset,t.byteLength);for(let e=0;e<d;e++){let t=e*c+l;for(let n=0;n<a;n++){let r=t+n*o;f[e*a+n]=i===`u8`?p.getUint8(r):i===`u16`?p.getUint16(r,!0):i===`u32`?p.getUint32(r,!0):p.getFloat32(r,!0)}}return new G(f,a,u)}function By(e){let{indices:t,indexType:n,indexCount:r}=e;if(!t||r===0)return null;let i=Math.floor(t.byteLength/r),a=i===4||i!==2&&(n===1||n===3),o=r*(a?4:2);if(o>t.byteLength)return null;let s=t.buffer.slice(t.byteOffset,t.byteOffset+o),c=a?new Uint32Array(s):new Uint16Array(s);return new G(c,1)}function Vy(e,t){let n=new Float32Array(t*3);if(!e)return n.fill(1),new G(n,3);let r=e.data,i=e.components??4,a=e.dtype===`u8`?1/255:1;for(let e=0;e<t;e++){let t=e*i;n[e*3]=(r[t]??255)*a,n[e*3+1]=(r[t+1]??255)*a,n[e*3+2]=(r[t+2]??255)*a}return new G(n,3)}function Hy(e){if(!e)return[];if(Array.isArray(e))return e;let t=e,n=t.materials??t.material;return Array.isArray(n)?n:[]}function Uy(e){return e?.material??e}function Wy(e){return e?.name??e?.id}function Gy(e){return(e?.textureStates??e?.textureunitstates??[]).map(e=>e?.textureunitstate??e).filter(e=>!!e)}function Ky(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 qy(e){let t=String(e?.cullMode??``).toUpperCase();return t===`CULL_BACK`||t===`BACKWARD`?0:t===`CULL_FRONT`?1:2}async function Jy(e,t={}){let n=t.uniforms??fy(),r=t.textureCache??new Map,i=new Ml,a=[],o=[],s={meshes:0,vertices:0,triangles:0,textures:0,instanced:0,edgeLines:0,skipped:[]},c=new Qu({color:new W(t.edgeColor??`#1f2937`),transparent:!0,opacity:.75,depthWrite:!1});i.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),i=r.get(e);if(i){let t=i.image;if((t?.width??0)*(t?.height??0)>=(n.width??0)*(n.height??0))continue;r.delete(e)}let{texture:a,decoded:c}=await cy(n);a?(r.set(e,a),o.push(e),s.textures++):s.skipped.push(`texture ${t} → ${c}`)}let u=Hy(e.materials),d=(e,t=!1)=>{let i=Uy(u.find(t=>Wy(Uy(t))===e)),a=Gy(i),o=a[0],s=o?r.get(l(Wy(o)??o.id??``))??null:null,c=a[1],d=globalThis.__S3M_NO_BAKE===!0,f=t&&c&&!d?r.get(l(Wy(c)??c.id??``))??null:null,p=o?.texmodmatrix??o?.matrix;if(s&&Array.isArray(p)&&p.length===16&&!Ky(p)&&(s=s.clone(),s.matrixAutoUpdate=!1,s.matrix.set(p[0],p[4],p[12],p[1],p[5],p[13],0,0,1)),s&&o?.addressmode){let e=o.addressmode.u,t=o.addressmode.v;(e!==void 0||t!==void 0)&&(s.matrixAutoUpdate&&(s=s.clone()),e!==void 0&&(s.wrapS=e===0?Ir:z),t!==void 0&&(s.wrapT=t===0?Ir:z))}let m=i?.diffuse??{r:1,g:1,b:1,a:1},h=i?.alphaMode,g=[o,c].some(e=>/\.water$/i.test(String(Wy(e)??e?.id??``))),_=h===`AM_BLEND`||(m.a??1)<.999||i?.transparentsorting===!0||g&&!s,v=typeof i?.shininess==`number`&&i.shininess>0?Math.max(.15,1-i.shininess/128):.95,y=s?.userData?.s3mHasAlpha?Math.max(i?.alphaCutoff??0,.01):0;return py({uniforms:n,map:s,color:g&&!s?Xy.clone():new W(m.r??1,m.g??1,m.b??1),side:qy(i),transparent:_,opacity:g&&!s?.86:m.a??1,roughness:g&&!s?.12:v,alphaTest:y,atlas:t&&!!s,secMap:f})},f=new Map,p=new Map;for(let[t,n]of Object.entries(e.geoPackage??{})){let r=n.vertexPackage,i=r.vertexAttributes.find(e=>e.semantic===`position`);if(!i){s.skipped.push(`${t} 无 position`);continue}let a=r.verticesCount||0,o={position:zy(i)},c=null,l=null;for(let e of r.vertexAttributes)e.divisor===void 0&&e.semantic!==`position`&&(e.semantic===`color`?c=e:e.semantic===`batchId`?l=e:e.semantic===`normal`?o.normal=zy(e):e.semantic===`uv`?o.uv=zy(e):e.semantic===`uv2`&&(o.uv1=zy(e)));o.aColor=Vy(c,a),o.aBatchId=l?zy(l):new G(new Float32Array(a).fill(-1),1);let u=e.atlasRects?.[t];if(u){o.aAtlasRect=new G(u.uv??new Float32Array(a*4),4);let e=o.uv1;u.uv2&&e?(o.aAtlasRect1=new G(u.uv2,4),o.aSecUv=e):(o.aAtlasRect1=new G(new Float32Array(a*4),4),o.aSecUv=o.uv??new G(new Float32Array(a*2),2))}let d=r.instanceIndex!==-1&&(r.instanceMode===16||r.instanceMode===17),m=n.indexPackages??[];m.length===0&&a>0&&(m=[{indexCount:0,indexType:0,useIndex:0,primitiveType:1,indices:null,passNames:[]}]),p.set(t,{indexPackages:m,instanced:d}),s.vertices+=a,m.forEach((e,n)=>{let r=new q;for(let[e,t]of Object.entries(o))r.setAttribute(e,t);let i=By(e);i?r.setIndex(i):r.setDrawRange(0,a),Ny(e.primitiveType)||Py(e.primitiveType)||r.getAttribute(`normal`)||r.computeVertexNormals(),r.computeBoundingBox(),r.computeBoundingSphere(),f.set(`${t}|${n}`,{geometry:r,pack:e})})}let m=new U,h=new Map,g=(e,t,n)=>{let r=0,i=0,a=!1,o=!1,s=!1,c=!1,l=!1,u=!1;for(let t of e){let e=t.cached.geometry,n=e.attributes.position?.count??0;r+=n,i+=e.index?e.index.count:n,e.attributes.normal&&(a=!0),e.attributes.uv&&(o=!0),e.attributes.uv1&&(s=!0),e.attributes.aColor&&(c=!0),e.attributes.aBatchId&&(l=!0),e.attributes.aAtlasRect&&(u=!0)}let d=new Float32Array(r*3),f=a?new Float32Array(r*3):null,p=o?new Float32Array(r*2):null,h=s?new Float32Array(r*2):null,g=c?new Float32Array(r*3):null,_=l?new Float32Array(r):null,v=u?new Float32Array(r*4):null,y=u?new Float32Array(r*4):null,b=u?new Float32Array(r*2):null,x=(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}},S=new(r>65535?Uint32Array:Uint16Array)(i),C=0,w=0,T=new H,E=new V,D=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&&a&&E.getNormalMatrix(r),t.geo.pickInfo)for(let e of Object.values(t.geo.pickInfo))typeof e.batchId==`number`&&e.batchId>=0&&D.set(e.batchId,t.geo);let o=e.attributes.position.array;for(let e=0;e<n;e++){let t=e*3,n=(C+e)*3;i?(T.set(o[t],o[t+1],o[t+2]).applyMatrix4(r),d[n]=T.x,d[n+1]=T.y,d[n+2]=T.z):(d[n]=o[t],d[n+1]=o[t+1],d[n+2]=o[t+2])}if(f){let t=e.attributes.normal;if(t){let e=t.array;for(let t=0;t<n;t++){let n=t*3,r=(C+t)*3;i?(T.set(e[n],e[n+1],e[n+2]).applyMatrix3(E).normalize(),f[r]=T.x,f[r+1]=T.y,f[r+2]=T.z):(f[r]=e[n],f[r+1]=e[n+1],f[r+2]=e[n+2])}}}if(p){let t=e.attributes.uv;if(t){let e=t.array;for(let t=0;t<n;t++)p[(C+t)*2]=e[t*2],p[(C+t)*2+1]=e[t*2+1]}}if(h){let t=e.attributes.uv1;if(t){let e=t.array;for(let t=0;t<n;t++)h[(C+t)*2]=e[t*2],h[(C+t)*2+1]=e[t*2+1]}}if(g){let t=e.attributes.aColor;if(t){let e=t.array;for(let t=0;t<n;t++)g[(C+t)*3]=e[t*3],g[(C+t)*3+1]=e[t*3+1],g[(C+t)*3+2]=e[t*3+2]}else for(let e=0;e<n;e++)g[(C+e)*3]=1,g[(C+e)*3+1]=1,g[(C+e)*3+2]=1}if(_){let t=e.attributes.aBatchId;if(t){let e=t.array;for(let t=0;t<n;t++)_[C+t]=e[t]}else for(let e=0;e<n;e++)_[C+e]=-1}if(v&&(x(v,e.attributes.aAtlasRect,4,n,C,(e,t)=>t.push(0,0,0,0)),x(y,e.attributes.aAtlasRect1,4,n,C,(e,t)=>t.push(0,0,0,0)),x(b,e.attributes.aSecUv,2,n,C)),e.index){let t=e.index.array,n=e.index.count;for(let e=0;e<n;e++)S[w+e]=t[e]+C;w+=n}else{for(let e=0;e<n;e++)S[w+e]=e+C;w+=n}C+=n}let O=new q;O.setAttribute(`position`,new G(d,3)),f&&O.setAttribute(`normal`,new G(f,3)),p&&O.setAttribute(`uv`,new G(p,2)),h&&O.setAttribute(`uv1`,new G(h,2)),g&&O.setAttribute(`aColor`,new G(g,3)),_&&O.setAttribute(`aBatchId`,new G(_,1)),v&&(O.setAttribute(`aAtlasRect`,new G(v,4)),O.setAttribute(`aAtlasRect1`,new G(y,4)),O.setAttribute(`aSecUv`,new G(b,2))),O.setIndex(new G(S,1)),O.computeBoundingBox(),O.computeBoundingSphere();let k=new dc(O,t);return k.userData.skeletonName=e[0].name,k.userData.geoRef=e[0].geo,k.userData.tileRef=n,k.userData.primitiveType=4,k.userData.isBatched=!0,k.userData.batchedCount=e.length,D.size>0&&(k.userData.geoByBatchId=D),k},_=(n,r,o,l)=>{let{geometry:u,pack:f}=n,h=d(f.passNames?.[0],!!u.getAttribute(`aAtlasRect`)),g,_=p.get(r),v=o.vertexPackage;if(Ny(f.primitiveType)){let e=new ld(u,c);return e.visible=t.edges===!0,e.renderOrder=2,e.raycast=()=>{},e.userData.isEdgeLines=!0,e.userData.skeletonName=r,l&&!l.equals(m)&&l.decompose(e.position,e.quaternion,e.scale),i.add(e),a.push(e),i.userData.hasNativeEdges=!0,s.edgeLines++,e}if(Py(f.primitiveType)){u.getAttribute(`color`)||u.setAttribute(`color`,u.getAttribute(`aColor`));let t=new gd(u,Fy());return t.userData.isPointCloud=!0,t.userData.skeletonName=r,t.userData.geoRef=o,t.userData.tileRef=e,t.userData.primitiveType=f.primitiveType,l&&!l.equals(m)&&l.decompose(t.position,t.quaternion,t.scale),i.add(t),a.push(t),s.meshes++,t}if(_?.instanced&&v.instanceBuffer&&v.instanceCount>0){if(!u.getAttribute(`aInstanceBatchId`)){let e=v.instanceBatchIds,t=e&&e.length===v.instanceCount?e.slice():new Float32Array(v.instanceCount).fill(-1);u.setAttribute(`aInstanceBatchId`,new Du(t,1));let n=new Float32Array(v.instanceCount);for(let e=0;e<n.length;e++)n[e]=e;u.setAttribute(`aInstanceIndex`,new Du(n,1))}let e=new Fu(u,h,v.instanceCount);e.instanceMatrix.setUsage(Ea);let t=new U,n=new W,r=v.instanceMode,i=new Float32Array(v.instanceBuffer.buffer,v.instanceBuffer.byteOffset,v.instanceCount*r);for(let a=0;a<v.instanceCount;a++){let o=a*r;if(t.set(i[o+0],i[o+1],i[o+2],i[o+3],i[o+4],i[o+5],i[o+6],i[o+7],i[o+8],i[o+9],i[o+10],i[o+11],0,0,0,1),e.setMatrixAt(a,t),r>=16){let t=i[o+12],r=i[o+13],s=i[o+14];Number.isFinite(t)&&Number.isFinite(r)&&Number.isFinite(s)&&(n.setRGB(t,r,s),e.setColorAt(a,n))}}e.instanceMatrix.needsUpdate=!0,e.instanceColor&&(e.instanceColor.needsUpdate=!0),e.frustumCulled=!1,s.instanced++,g=e}else g=new dc(u,h);return l&&!l.equals(m)&&l.decompose(g.position,g.quaternion,g.scale),g.userData.skeletonName=r,g.userData.geoRef=o,g.userData.tileRef=e,g.userData.primitiveType=f.primitiveType,i.add(g),a.push(g),s.meshes++,f.primitiveType===4&&(s.triangles+=(f.indexCount||0)/3),g},v=0;for(let n of e.groupNode?.pageLods??[])for(let r of n.geodes??[]){let n=r.matrix,i=n&&n.length===16?new U().fromArray(n):null;for(let n of r.skeletonNames??[]){let r=p.get(n);if(!r)continue;let a=e.geoPackage[n];if(!a)continue;let o=a.vertexPackage;for(let e=0;e<r.indexPackages.length;e++){let s=f.get(`${n}|${e}`);if(s){if(Ny(s.pack.primitiveType)||r.instanced&&o.instanceBuffer&&o.instanceCount>0)_(s,n,a,i),v++;else if(t.batching!==!1&&s.pack.primitiveType===4){let e=s.pack.passNames?.[0]??`__default__`,t=h.get(e);t||(t=[],h.set(e,t)),t.push({cached:s,name:n,geo:a,matrix:i}),v++}else _(s,n,a,i),v++}}}}if(v===0)for(let[n,r]of p){let i=e.geoPackage[n];if(!i)continue;let a=i.vertexPackage;for(let e=0;e<r.indexPackages.length;e++){let o=f.get(`${n}|${e}`);if(o){if(Ny(o.pack.primitiveType)||r.instanced&&a.instanceBuffer&&a.instanceCount>0)_(o,n,i,null);else if(t.batching!==!1&&o.pack.primitiveType===4){let e=o.pack.passNames?.[0]??`__default__`,t=h.get(e);t||(t=[],h.set(e,t)),t.push({cached:o,name:n,geo:i,matrix:null})}else _(o,n,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`),o=g(n,d(t===`__default__`?void 0:t,r),e);i.add(o),a.push(o),s.meshes++;for(let e of n)s.triangles+=(e.cached.pack.indexCount||0)/3}return i.children.length||s.skipped.push(`tile 无可用几何`),i.userData.textureKeys=o,{group:i,stats:s,objects:a,textureKeys:o}}var Yy,Xy,Zy=n((()=>{rh(),dy(),jy(),Yy=null,Xy=new W(1920611)}));function Qy(e){return e.slice(0,e.lastIndexOf(`/`)+1)}function $y(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 eb(e,t){if(!t)return null;try{return tb(new URL(t,e).href)}catch{return tb(`${Qy(e)}${t}`)}}function tb(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 nb=110540,rb=111320;function ib(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 ab(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?eb(Qy(e),n):tb(`${r[r.length-1]===`path`&&r[r.length-2]===`data`?`${r.join(`/`)}/${a}`:`${r.join(`/`)}/data/path/${a}`}/${n}`)}function ob(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=rb*Math.cos(i*Math.PI/180);n>1e-6&&(o=r+e/n,s=r+t/n,l=i+a/nb,c=i+u/nb)}}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 sb=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){X(this,`configUrl`,void 0),X(this,`config`,null),X(this,`_blockTileIndex`,null),X(this,`anchor`,{lon:0,lat:0,height:0}),X(this,`rootUrls`,[]),X(this,`nodes`,new Map),X(this,`failed`,new Set),X(this,`textureCache`,new Map),X(this,`maxImageCache`,void 0),X(this,`_textureRefs`,new Map),X(this,`_tileTextureKeys`,new Map),X(this,`pending`,new Set),X(this,`atlasLod`,void 0),X(this,`atlasLodCache`,new Map),X(this,`_groupCache`,new Map),X(this,`externalAtlasCache`,new Map),X(this,`leafRequestCache`,new Map),X(this,`_leafPending`,new Map),X(this,`atlasUpgraded`,new Set),X(this,`atlasUpgradeSkipped`,new Map),X(this,`stats`,{tiles:0,loading:0,failed:0,meshes:0,vertices:0,triangles:0,datasets:1}),X(this,`maxConcurrent`,void 0),X(this,`maxTiles`,void 0),X(this,`lodRangeScale`,void 0),X(this,`_onTile`,void 0),X(this,`_onTileRemoved`,void 0),X(this,`_onError`,void 0),X(this,`_onProgress`,void 0),X(this,`_maxRetries`,void 0),X(this,`_retryCount`,new Map),X(this,`_retryAt`,new Map),X(this,`_parentOf`,new Map),X(this,`_frame`,0),X(this,`_lodDbgOnce`,!1),X(this,`_permanentReported`,!1),X(this,`hardCap`,96),X(this,`isS3MV1`,!1),X(this,`_buildTile`,void 0),X(this,`_uniforms`,void 0),X(this,`_queue`,[]),X(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=$y(this.configUrl);let e=await fetch(this.configUrl);if(!e.ok)throw Error(`配置读取失败 ${e.status} ${this.configUrl}`);let t=ob(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=eb(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=eb(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=ib(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(()=>(Zy(),My));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=j_(n),a=!1,o=new Map,s=new Map,c=[];for(let[e,t]of Object.entries(r)){let n=V_(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=H_(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=ev(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)&&M_(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=eb(Qy(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 F_(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=eb(Qy(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 F_(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 U_(t);this._rememberGroups(n,e),o=e.names,a=e.tiles[r]??e.tiles[0]}else a=await qg(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?ab(e,t.childTile):eb(Qy(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?ab(e,f?.childTile):eb(Qy(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()}};rh(),jy();var cb=2;function lb(e){return e===hy.SOLID?`solid`:e===hy.HEIGHT?`height`:`vertex`}var ub=`
4199
4199
  uniform float uPointSize;
4200
4200
  varying float vWorldZ;
4201
4201
  void main() {
@@ -4204,7 +4204,7 @@ void main() {
4204
4204
  gl_Position = projectionMatrix * viewMatrix * world;
4205
4205
  gl_PointSize = uPointSize;
4206
4206
  }
4207
- `,fb=`
4207
+ `,db=`
4208
4208
  uniform vec3 uColorA;
4209
4209
  uniform vec3 uColorB;
4210
4210
  uniform float uHeightMin;
@@ -4215,13 +4215,13 @@ void main() {
4215
4215
  float h = clamp( ( vWorldZ - uHeightMin ) / max( uHeightMax - uHeightMin, 0.001 ), 0.0, 1.0 );
4216
4216
  gl_FragColor = vec4( mix( uColorA, uColorB, h ), uOpacity );
4217
4217
  }
4218
- `,pb=`
4218
+ `,fb=`
4219
4219
  uniform vec3 uSelColor;
4220
4220
  uniform float uOpacity;
4221
4221
  void main() {
4222
4222
  gl_FragColor = vec4( uSelColor, uOpacity );
4223
4223
  }
4224
- `;function mb(e,t,n){let r;return r=e===`height`?new gc({uniforms:{uColorA:n.uColorA,uColorB:n.uColorB,uHeightMin:n.uHeightMin,uHeightMax:n.uHeightMax,uPointSize:{value:lb},uOpacity:{value:t.opacity??1}},vertexShader:db,fragmentShader:fb,transparent:(t.opacity??1)<.999,depthWrite:(t.opacity??1)>=.999}):e===`selected`?new gc({uniforms:{uSelColor:n.uSelColor,uPointSize:{value:lb},uOpacity:{value:t.opacity??1}},vertexShader:db,fragmentShader:pb,transparent:(t.opacity??1)<.999,depthWrite:(t.opacity??1)>=.999}):e===`solid`?new dd({size:lb,sizeAttenuation:!1,color:new W(t.colorA),transparent:(t.opacity??1)<.999,opacity:t.opacity??1,depthWrite:(t.opacity??1)>=.999}):new dd({size:lb,sizeAttenuation:!1,vertexColors:!0,transparent:(t.opacity??1)<.999,opacity:t.opacity??1,depthWrite:(t.opacity??1)>=.999}),r.userData.pcOwned=!0,r}function hb(e,t,n,r=!1){let i=e.userData,a=r?`selected`:ub(t.mode);if(i.pcKind!==a){let r=e.material;e.material=mb(a,t,n),r&&r.userData?.pcOwned&&r.dispose(),i.pcKind=a,i.pcTransparent=void 0}else a===`solid`&&e.material.color?.set(t.colorA);let o=Math.min(1,Math.max(.05,t.opacity??1)),s=o<.999,c=t.depthWrite!==!1,l=e.material;l.transparent=s,l.opacity=o,l.depthWrite=!s||c,l.uniforms?.uOpacity&&(l.uniforms.uOpacity.value=o),i.pcTransparent!==s&&(i.pcTransparent=s,l.needsUpdate=!0)}function gb(e){let t=Array.isArray(e)?e[0]:e;return!!t&&t.userData?.pcOwned===!0}rh();var _b=`
4224
+ `;function pb(e,t,n){let r;return r=e===`height`?new gc({uniforms:{uColorA:n.uColorA,uColorB:n.uColorB,uHeightMin:n.uHeightMin,uHeightMax:n.uHeightMax,uPointSize:{value:cb},uOpacity:{value:t.opacity??1}},vertexShader:ub,fragmentShader:db,transparent:(t.opacity??1)<.999,depthWrite:(t.opacity??1)>=.999}):e===`selected`?new gc({uniforms:{uSelColor:n.uSelColor,uPointSize:{value:cb},uOpacity:{value:t.opacity??1}},vertexShader:ub,fragmentShader:fb,transparent:(t.opacity??1)<.999,depthWrite:(t.opacity??1)>=.999}):e===`solid`?new dd({size:cb,sizeAttenuation:!1,color:new W(t.colorA),transparent:(t.opacity??1)<.999,opacity:t.opacity??1,depthWrite:(t.opacity??1)>=.999}):new dd({size:cb,sizeAttenuation:!1,vertexColors:!0,transparent:(t.opacity??1)<.999,opacity:t.opacity??1,depthWrite:(t.opacity??1)>=.999}),r.userData.pcOwned=!0,r}function mb(e,t,n,r=!1){let i=e.userData,a=r?`selected`:lb(t.mode);if(i.pcKind!==a){let r=e.material;e.material=pb(a,t,n),r&&r.userData?.pcOwned&&r.dispose(),i.pcKind=a,i.pcTransparent=void 0}else a===`solid`&&e.material.color?.set(t.colorA);let o=Math.min(1,Math.max(.05,t.opacity??1)),s=o<.999,c=t.depthWrite!==!1,l=e.material;l.transparent=s,l.opacity=o,l.depthWrite=!s||c,l.uniforms?.uOpacity&&(l.uniforms.uOpacity.value=o),i.pcTransparent!==s&&(i.pcTransparent=s,l.needsUpdate=!0)}function hb(e){let t=Array.isArray(e)?e[0]:e;return!!t&&t.userData?.pcOwned===!0}rh();var gb=`
4225
4225
  attribute float aBatchId;
4226
4226
  #ifdef USE_INSTANCING
4227
4227
  // 实例化:单体粒度在实例上,顶点属性里没有可用的 batchId
@@ -4277,7 +4277,7 @@ void main() {
4277
4277
  // 跟显示尺寸(2px)不匹配,点云会很难点中。对 Mesh 图元这行被忽略。
4278
4278
  gl_PointSize = 2.0;
4279
4279
  }
4280
- `,vb=`
4280
+ `,_b=`
4281
4281
  uniform float uObjectId;
4282
4282
  varying float vBatch;
4283
4283
  void main() {
@@ -4290,7 +4290,7 @@ void main() {
4290
4290
  floor( b / 256.0 ) / 255.0
4291
4291
  );
4292
4292
  }
4293
- `,yb=(()=>{let e=new Cu(new Float32Array([-1,-1,-1,0,0,0,0,0]),1,2,ci,ei);return e.minFilter=Rr,e.magFilter=Rr,e.needsUpdate=!0,e})();function bb(e){return new gc({uniforms:{uObjectId:{value:e},uBatchTex:{value:yb},uBatchTexWidth:{value:1},uBatchTexActive:{value:0},uSelBatch:{value:-1},uSelWhole:{value:0},uSelElevation:{value:0}},vertexShader:_b,fragmentShader:vb,side:2,depthTest:!0,depthWrite:!0,toneMapped:!1})}function xb(e){return e.isPoints===!0}var Sb=class{constructor(e,t={}){X(this,`renderer`,void 0),X(this,`size`,void 0),X(this,`target`,null),X(this,`buf`,new Uint8Array(4)),this.renderer=e,this.size=Math.max(1,Math.floor(t.size??1))}_ensureTarget(e){return this.target&&this.target.width===e&&this.target.height===e||(this.target?.dispose(),this.target=new oo(e,e,{minFilter:Rr,magFilter:Rr,format:ci,type:Jr,depthBuffer:!0,stencilBuffer:!1}),this.target.texture.colorSpace=pa),this.target}pick(e,t,n,r){let i=this.renderer,a=i.domElement,o=a.width,s=a.height;if(!o||!s)return null;let c=Math.floor(n/a.clientWidth*o),l=Math.floor(r/a.clientHeight*s);if(c<0||l<0||c>=o||l>=s)return null;let u=this._ensureTarget(this.size),d=s-1-l,f=Math.floor(this.size/2),p=Math.floor(this.size/2);u.viewport.set(f-c,p-d,o,s);let m=i.getRenderTarget(),h=i.getViewport(new io),g=i.toneMapping,_=i.outputColorSpace,v=i.autoClear,y=i.getClearColor(new W),b=i.getClearAlpha(),x=[],S=new Set;e.traverseVisible(e=>{let t=e;if(!t.isMesh&&!xb(t))return;let n=t.userData;if(n.pickId===void 0)return;n.pickMaterial||(n.pickMaterial=bb(n.pickId)),t.isInstancedMesh&&S.add(n.pickId);let r=t.material,i=n.pickMaterial,a=Array.isArray(r)?r[0]:r,o=a?.userData?.uBatchTex;o?(i.uniforms.uBatchTex.value=o.value,i.uniforms.uBatchTexWidth.value=a?.userData?.uBatchTexWidth?.value??1,i.uniforms.uBatchTexActive.value=a?.userData?.uBatchTexActive?.value??0):(i.uniforms.uBatchTex.value=yb,i.uniforms.uBatchTexWidth.value=1,i.uniforms.uBatchTexActive.value=0),i.uniforms.uSelBatch.value=a?.userData?.uSelBatch?.value??-1,i.uniforms.uSelWhole.value=a?.userData?.uSelWhole?.value??0,i.uniforms.uSelElevation.value=a?.uniforms?.uSelElevation?.value??0,x.push([t,r]),t.material=i});let C=[];e.traverseVisible(e=>{let t=e;(t.isMesh||xb(t))&&t.userData.pickId===void 0&&(C.push(t),t.visible=!1)});let w=null;try{i.resetState(),i.setRenderTarget(u),i.toneMapping=0,i.outputColorSpace=pa,i.autoClear=!0,i.setClearColor(0,0),i.clear(),i.render(e,t),i.readRenderTargetPixels(u,f,p,1,1,this.buf);let n=this.buf[0],r=this.buf[1],a=this.buf[2],o=this.buf[3],s=n+r*256-1,c=a+o*256-1;s>=0&&(w=S.has(s)?{objectId:s,batchId:-1,instanceIndex:Math.max(0,c)}:{objectId:s,batchId:c})}finally{for(let[e,t]of x)e.material=t;for(let e of C)e.visible=!0;i.setRenderTarget(m),i.setViewport(h),i.toneMapping=g,i.outputColorSpace=_,i.autoClear=v,i.setClearColor(y,b),i.resetState()}return w}dispose(){this.target?.dispose(),this.target=null}};rh();function Cb(){return{uResolution:{value:new B(1,1)},uDpr:{value:1}}}var wb=`
4293
+ `,vb=(()=>{let e=new Cu(new Float32Array([-1,-1,-1,0,0,0,0,0]),1,2,ci,ei);return e.minFilter=Rr,e.magFilter=Rr,e.needsUpdate=!0,e})();function yb(e){return new gc({uniforms:{uObjectId:{value:e},uBatchTex:{value:vb},uBatchTexWidth:{value:1},uBatchTexActive:{value:0},uSelBatch:{value:-1},uSelWhole:{value:0},uSelElevation:{value:0}},vertexShader:gb,fragmentShader:_b,side:2,depthTest:!0,depthWrite:!0,toneMapped:!1})}function bb(e){return e.isPoints===!0}var xb=class{constructor(e,t={}){X(this,`renderer`,void 0),X(this,`size`,void 0),X(this,`target`,null),X(this,`buf`,new Uint8Array(4)),this.renderer=e,this.size=Math.max(1,Math.floor(t.size??1))}_ensureTarget(e){return this.target&&this.target.width===e&&this.target.height===e||(this.target?.dispose(),this.target=new oo(e,e,{minFilter:Rr,magFilter:Rr,format:ci,type:Jr,depthBuffer:!0,stencilBuffer:!1}),this.target.texture.colorSpace=pa),this.target}pick(e,t,n,r){let i=this.renderer,a=i.domElement,o=a.width,s=a.height;if(!o||!s)return null;let c=Math.floor(n/a.clientWidth*o),l=Math.floor(r/a.clientHeight*s);if(c<0||l<0||c>=o||l>=s)return null;let u=this._ensureTarget(this.size),d=s-1-l,f=Math.floor(this.size/2),p=Math.floor(this.size/2);u.viewport.set(f-c,p-d,o,s);let m=i.getRenderTarget(),h=i.getViewport(new io),g=i.toneMapping,_=i.outputColorSpace,v=i.autoClear,y=i.getClearColor(new W),b=i.getClearAlpha(),x=[],S=new Set;e.traverseVisible(e=>{let t=e;if(!t.isMesh&&!bb(t))return;let n=t.userData;if(n.pickId===void 0)return;n.pickMaterial||(n.pickMaterial=yb(n.pickId)),t.isInstancedMesh&&S.add(n.pickId);let r=t.material,i=n.pickMaterial,a=Array.isArray(r)?r[0]:r,o=a?.userData?.uBatchTex;o?(i.uniforms.uBatchTex.value=o.value,i.uniforms.uBatchTexWidth.value=a?.userData?.uBatchTexWidth?.value??1,i.uniforms.uBatchTexActive.value=a?.userData?.uBatchTexActive?.value??0):(i.uniforms.uBatchTex.value=vb,i.uniforms.uBatchTexWidth.value=1,i.uniforms.uBatchTexActive.value=0),i.uniforms.uSelBatch.value=a?.userData?.uSelBatch?.value??-1,i.uniforms.uSelWhole.value=a?.userData?.uSelWhole?.value??0,i.uniforms.uSelElevation.value=a?.uniforms?.uSelElevation?.value??0,x.push([t,r]),t.material=i});let C=[];e.traverseVisible(e=>{let t=e;(t.isMesh||bb(t))&&t.userData.pickId===void 0&&(C.push(t),t.visible=!1)});let w=null;try{i.resetState(),i.setRenderTarget(u),i.toneMapping=0,i.outputColorSpace=pa,i.autoClear=!0,i.setClearColor(0,0),i.clear(),i.render(e,t),i.readRenderTargetPixels(u,f,p,1,1,this.buf);let n=this.buf[0],r=this.buf[1],a=this.buf[2],o=this.buf[3],s=n+r*256-1,c=a+o*256-1;s>=0&&(w=S.has(s)?{objectId:s,batchId:-1,instanceIndex:Math.max(0,c)}:{objectId:s,batchId:c})}finally{for(let[e,t]of x)e.material=t;for(let e of C)e.visible=!0;i.setRenderTarget(m),i.setViewport(h),i.toneMapping=g,i.outputColorSpace=_,i.autoClear=v,i.setClearColor(y,b),i.resetState()}return w}dispose(){this.target?.dispose(),this.target=null}};rh();function Sb(){return{uResolution:{value:new B(1,1)},uDpr:{value:1}}}var Cb=`
4294
4294
  attribute vec3 aOther;
4295
4295
  attribute float aSide;
4296
4296
 
@@ -4328,7 +4328,7 @@ void main() {
4328
4328
 
4329
4329
  gl_Position = vec4( ndc * clipA.w, clipA.z, clipA.w );
4330
4330
  }
4331
- `,Tb=`
4331
+ `,wb=`
4332
4332
  uniform vec3 uColor;
4333
4333
  uniform float uOpacity;
4334
4334
 
@@ -4336,7 +4336,7 @@ void main() {
4336
4336
  if ( uOpacity <= 0.003 ) discard;
4337
4337
  gl_FragColor = vec4( uColor, uOpacity );
4338
4338
  }
4339
- `;function Eb(e,t={}){let n=new gc({uniforms:{uResolution:e.uResolution,uDpr:e.uDpr,uColor:{value:new W(t.color??`#ffffff`)},uOpacity:{value:t.opacity??1},uWidth:{value:t.width??1.5},uElevation:{value:t.elevation??0},uTranslation:{value:new H(0,0,0)}},vertexShader:wb,fragmentShader:Tb,transparent:!0,depthWrite:!1,side:2,polygonOffset:!0,polygonOffsetFactor:-2,polygonOffsetUnits:-2});return n.userData.isThickLine=!0,n}function Db(e){let t=Math.floor(e.length/6),n=t*4,r=new Float32Array(n*3),i=new Float32Array(n*3),a=new Float32Array(n),o=n>65535?new Uint32Array(t*6):new Uint16Array(t*6);for(let n=0;n<t;n++){let t=n*6,r=e[t],i=e[t+1],a=e[t+2],c=e[t+3],l=e[t+4],u=e[t+5],d=n*4;s(d,r,i,a,c,l,u,-1),s(d+1,r,i,a,c,l,u,1),s(d+2,c,l,u,r,i,a,1),s(d+3,c,l,u,r,i,a,-1);let f=n*6;o[f]=d,o[f+1]=d+1,o[f+2]=d+2,o[f+3]=d,o[f+4]=d+2,o[f+5]=d+3}function s(e,t,n,o,s,c,l,u){let d=e*3;r[d]=t,r[d+1]=n,r[d+2]=o,i[d]=s,i[d+1]=c,i[d+2]=l,a[e]=u}let c=new q;return c.setAttribute(`position`,new G(r,3)),c.setAttribute(`aOther`,new G(i,3)),c.setAttribute(`aSide`,new G(a,1)),c.setIndex(new G(o,1)),c.computeBoundingSphere(),c}var Ob=6e4,kb=100;function Ab(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]*kb)},${Math.round(o[n]*kb)},${Math.round(s[n]*kb)}`,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>=Ob*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}rh();var jb=class{constructor(){X(this,`datasets`,new Map),X(this,`sceneAnchor`,null),X(this,`totalMaxTiles`,0)}get(e){return this.datasets.get(e)}values(){return this.datasets.values()}registerDataset(e){let t=this.datasets.get(e.id);if(t)return t;let n=new Ml;n.name=`s3m-dataset:${e.id}`,n.visible=e.visible!==!1;let r={id:e.id,name:e.name??e.id,options:e,root:n,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,r),this.rebalanceBudgets(),r}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,t,n,r,i,a,o,s,c){let l=this.datasets.get(e.id);if(l)return l;let u=new Ml;u.name=`s3m-dataset:${e.id}`,u.visible=e.visible!==!1,t.add(u);let d={id:e.id,name:e.name??e.id,options:e,root:u,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,d);let f=new sb({configUrl:e.configUrl,maxTiles:e.maxTiles??o,maxConcurrent:s,lodRangeScale:e.lodRangeScale??i,buildTile:a??null,uniforms:r,onTile:e=>{c.onTile(e,d)},onTileRemoved:e=>{c.onTileRemoved(e,d)},onProgress:()=>{c.onStats(),c.triggerRepaint()},onError:e=>{d.error=e,c.onError(e),c.onStats()}});d.tileset=f,this.rebalanceBudgets();try{await f.init()}catch(e){return d.error=e,c.onError(e),d}return d.anchor=f.anchor,d.baseAlignOffset=this.computeAlignOffset(f,e.align),d.userOffset=e.heightOffset??0,d.heightOffset=d.baseAlignOffset+d.userOffset,this.layoutDataset(d,n),c.onReady(d),c.triggerRepaint(),d}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=u_(t,e.anchor.lon,e.anchor.lat,e.anchor.height??0));let n=this.sceneAnchor.meterInMercator,r=u_(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=ib(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}};rh(),t_();function Mb(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function Nb(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 Pb(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 Fb(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 Ib=class{constructor(e,t,n,r,i){X(this,`_getLayerFloorHeight`,void 0),X(this,`_triggerRepaint`,void 0),X(this,`_onStyleChanged`,void 0),X(this,`_getAllMeshes`,void 0),X(this,`_applyOverrideHook`,void 0),X(this,`featureStyles`,new Map),X(this,`thematicColors`,new Map),X(this,`thematicElevation`,new Map),X(this,`thematicField`,null),X(this,`elevationField`,null),X(this,`filter`,null),X(this,`fieldFilter`,null),X(this,`_meshBatchTextures`,new WeakMap),X(this,`_markedMeshes`,new Set),X(this,`_dirtyAll`,!1),X(this,`_flushScheduled`,!1),X(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,t,n){if(!t)throw Error(`[s3m] 未配置业务属性数据源,先调用 setAttributeSource() 或构造时传 attributes`);let r=e.smids?.length?[...new Set(e.smids)]:n;if(!r.length)return this.clearThematicColors(),{field:e.field,type:`discrete`,matched:0,missing:0,legend:[]};let i=await t.queryBySmids(r),a=[],o=[];for(let t of r){let n=i.get(t),r=n?n[e.field]:void 0;if(r==null||r===``)continue;let s=Number(r);Number.isFinite(s)?a.push({smid:t,val:s}):o.push({smid:t,val:String(r)})}let s=a.length>=o.length&&a.length>0,c=new Map,l=[],u=e.defaultColor??`#64748b`,d=e.nullColor??`#334155`;if(s){let t=a.map(e=>e.val),n=Math.min(...t),r=Math.max(...t)-n||1,i=(e.ramp??[`#3b82f6`,`#10b981`,`#f59e0b`,`#ef4444`]).map(e=>new W(e)),o=Math.max(2,e.stops??5);for(let e=0;e<o;e++){let t=e/o,a=(e+1)/o,s=Nb(i,(t+a)/2),c=n+t*r,u=n+a*r;l.push({color:`#${s.getHexString()}`,label:`${Fb(c)} ~ ${Fb(u)}`,count:0,min:c,max:u})}for(let{smid:e,val:t}of a){let i=Math.min(1,Math.max(0,(t-n)/r)),a=Math.min(o-1,Math.floor(i*o)),s=l[a].color;c.set(e,s),l[a].count++}}else{let t=new Map;for(let{val:e}of o)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];l.push({color:o,label:t,count:a})}let a=new Map(l.map(e=>[e.label,e.color]));for(let{smid:e,val:t}of o)c.set(e,a.get(t)??u)}let f=0;for(let e of r)c.has(e)||(c.set(e,d),f++);return f>0&&l.push({color:d,label:`无数据 / 缺失`,count:f}),this.setThematicColors(c,e.field),{field:e.field,type:s?`continuous`:`discrete`,matched:r.length-f,missing:f,legend:l}}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?Pb(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=Jg(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 t=Mb(e);if(!t)return;let n=e.userData,r=n.geoRef?.pickInfo,i=this.featureStyles.size>0||this.thematicColors.size>0||this.thematicElevation.size>0,a=this.filter,o=this.fieldFilter!=null||a!=null&&((a.include?.length??0)>0||(a.exclude?.length??0)>0||a.predicate!=null);if(!i&&!o||!r||Object.keys(r).length===0){t.userData.uBatchTexActive&&(t.userData.uBatchTexActive.value=0);return}let s=0;for(let e of Object.values(r)){let t=Jg(e);t>s&&(s=t)}let c=Math.max(s+1,1),l=this._meshBatchTextures.get(e);if(!l||l.width<c){let n=new Float32Array(c*2*4),r=new Cu(n,c,2,ci,ei);r.minFilter=Rr,r.magFilter=Rr,l={texture:r,data:n,width:c},this._meshBatchTextures.set(e,l),t.userData.uBatchTex.value=r,t.userData.uBatchTexWidth.value=c}let{data:u,texture:d}=l,f=l.width;for(let e=0;e<f;e++){u[e*4+0]=-1,u[e*4+1]=-1,u[e*4+2]=-1,u[e*4+3]=0;let t=(f+e)*4;u[t+0]=0,u[t+1]=0,u[t+2]=0,u[t+3]=0}let p=!1,m=new Set,h=new Map,g=new Map,_=new Map,v=new Map;for(let[t,i]of Object.entries(r)){let r=Number(t),o=Jg(i);if(o<0||o>=l.width)continue;v.set(o,(v.get(o)??0)+1);let s=!1;if(a&&(a.include&&a.include.length>0&&!a.include.includes(r)&&(s=!0),a.exclude&&a.exclude.length>0&&a.exclude.includes(r)&&(s=!0),a.predicate)){let{segments:t}=Xg(n.geoRef,o),i=Qg({smid:r,box:Zg(e.geometry,t),triangles:0,floorHeight:this._getLayerFloorHeight()});a.predicate({...i,smid:r})||(s=!0)}if(s){m.add(o);continue}if(this.fieldFilter){let e=this.fieldFilter.matched.has(r);if(this.fieldFilter.mode===`keep`?!e:e){m.add(o);continue}}let c=this.featureStyles.get(r);if(c?.hidden){m.add(o);continue}let u=c?.color??this.thematicColors.get(r);u&&!h.has(o)&&h.set(o,u);let d=c?.elevation??this.thematicElevation.get(r);d!=null&&!g.has(o)&&g.set(o,d),c?.translation&&!_.has(o)&&_.set(o,c.translation)}for(let e of m)u[e*4+3]=-1,p=!0;let y=new W;for(let[e,t]of h)m.has(e)||(y.set(t),u[e*4+0]=y.r,u[e*4+1]=y.g,u[e*4+2]=y.b,p=!0);for(let[e,t]of g){if(m.has(e))continue;u[e*4+3]=t;let n=(f+e)*4;u[n+2]=t,p=!0}for(let[e,t]of _){if(m.has(e))continue;let n=(f+e)*4;u[n+0]=t[0],u[n+1]=t[1],u[n+2]=t[2]+(g.get(e)??0),p=!0}let b=0;for(let[e,t]of v)t<2||(m.has(e)||h.has(e)||g.has(e))&&b++;b>0&&!this._batchConflictWarned&&(this._batchConflictWarned=!0,console.warn(`[s3m] 有 ${b} 个单体状态写不进独立的 batch(多个 SMID 共用同一个 batchId,\n S3M 的单体化粒度只到 batch,无法单独隐藏/改色其中一部分)。
4339
+ `;function Tb(e,t={}){let n=new gc({uniforms:{uResolution:e.uResolution,uDpr:e.uDpr,uColor:{value:new W(t.color??`#ffffff`)},uOpacity:{value:t.opacity??1},uWidth:{value:t.width??1.5},uElevation:{value:t.elevation??0},uTranslation:{value:new H(0,0,0)}},vertexShader:Cb,fragmentShader:wb,transparent:!0,depthWrite:!1,side:2,polygonOffset:!0,polygonOffsetFactor:-2,polygonOffsetUnits:-2});return n.userData.isThickLine=!0,n}function Eb(e){let t=Math.floor(e.length/6),n=t*4,r=new Float32Array(n*3),i=new Float32Array(n*3),a=new Float32Array(n),o=n>65535?new Uint32Array(t*6):new Uint16Array(t*6);for(let n=0;n<t;n++){let t=n*6,r=e[t],i=e[t+1],a=e[t+2],c=e[t+3],l=e[t+4],u=e[t+5],d=n*4;s(d,r,i,a,c,l,u,-1),s(d+1,r,i,a,c,l,u,1),s(d+2,c,l,u,r,i,a,1),s(d+3,c,l,u,r,i,a,-1);let f=n*6;o[f]=d,o[f+1]=d+1,o[f+2]=d+2,o[f+3]=d,o[f+4]=d+2,o[f+5]=d+3}function s(e,t,n,o,s,c,l,u){let d=e*3;r[d]=t,r[d+1]=n,r[d+2]=o,i[d]=s,i[d+1]=c,i[d+2]=l,a[e]=u}let c=new q;return c.setAttribute(`position`,new G(r,3)),c.setAttribute(`aOther`,new G(i,3)),c.setAttribute(`aSide`,new G(a,1)),c.setIndex(new G(o,1)),c.computeBoundingSphere(),c}var Db=6e4,Ob=100;function kb(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]*Ob)},${Math.round(o[n]*Ob)},${Math.round(s[n]*Ob)}`,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>=Db*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}rh();function Ab(e,t){let n=e.getAttribute(`position`);if(!n||n.count===0)return e;let r=1/Math.max(t,1e-9),i=new Map,a=[],o=new Int32Array(n.count);for(let e=0;e<n.count;e++){let t=n.getX(e),s=n.getY(e),c=n.getZ(e),l=`${Math.round(t*r)},${Math.round(s*r)},${Math.round(c*r)}`,u=i.get(l);u===void 0&&(u=a.length/3,a.push(t,s,c),i.set(l,u)),o[e]=u}let s=e.getIndex(),c=s?s.count:n.count,l=new Uint32Array(c);for(let e=0;e<c;e++)l[e]=o[s?s.getX(e):e];let u=new q;return u.setAttribute(`position`,new K(a,3)),u.setIndex(new G(l,1)),u}rh();var jb=class{constructor(){X(this,`datasets`,new Map),X(this,`sceneAnchor`,null),X(this,`totalMaxTiles`,0)}get(e){return this.datasets.get(e)}values(){return this.datasets.values()}registerDataset(e){let t=this.datasets.get(e.id);if(t)return t;let n=new Ml;n.name=`s3m-dataset:${e.id}`,n.visible=e.visible!==!1;let r={id:e.id,name:e.name??e.id,options:e,root:n,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,r),this.rebalanceBudgets(),r}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,t,n,r,i,a,o,s,c){let l=this.datasets.get(e.id);if(l)return l;let u=new Ml;u.name=`s3m-dataset:${e.id}`,u.visible=e.visible!==!1,t.add(u);let d={id:e.id,name:e.name??e.id,options:e,root:u,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,d);let f=new sb({configUrl:e.configUrl,maxTiles:e.maxTiles??o,maxConcurrent:s,lodRangeScale:e.lodRangeScale??i,buildTile:a??null,uniforms:r,onTile:e=>{c.onTile(e,d)},onTileRemoved:e=>{c.onTileRemoved(e,d)},onProgress:()=>{c.onStats(),c.triggerRepaint()},onError:e=>{d.error=e,c.onError(e),c.onStats()}});d.tileset=f,this.rebalanceBudgets();try{await f.init()}catch(e){return d.error=e,c.onError(e),d}return d.anchor=f.anchor,d.baseAlignOffset=this.computeAlignOffset(f,e.align),d.userOffset=e.heightOffset??0,d.heightOffset=d.baseAlignOffset+d.userOffset,this.layoutDataset(d,n),c.onReady(d),c.triggerRepaint(),d}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=u_(t,e.anchor.lon,e.anchor.lat,e.anchor.height??0));let n=this.sceneAnchor.meterInMercator,r=u_(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=ib(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}};rh(),t_();function Mb(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function Nb(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 Pb(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 Fb(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 Ib=class{constructor(e,t,n,r,i){X(this,`_getLayerFloorHeight`,void 0),X(this,`_triggerRepaint`,void 0),X(this,`_onStyleChanged`,void 0),X(this,`_getAllMeshes`,void 0),X(this,`_applyOverrideHook`,void 0),X(this,`featureStyles`,new Map),X(this,`thematicColors`,new Map),X(this,`thematicElevation`,new Map),X(this,`thematicField`,null),X(this,`elevationField`,null),X(this,`filter`,null),X(this,`fieldFilter`,null),X(this,`_meshBatchTextures`,new WeakMap),X(this,`_markedMeshes`,new Set),X(this,`_dirtyAll`,!1),X(this,`_flushScheduled`,!1),X(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,t,n){if(!t)throw Error(`[s3m] 未配置业务属性数据源,先调用 setAttributeSource() 或构造时传 attributes`);let r=e.smids?.length?[...new Set(e.smids)]:n;if(!r.length)return this.clearThematicColors(),{field:e.field,type:`discrete`,matched:0,missing:0,legend:[]};let i=await t.queryBySmids(r),a=[],o=[];for(let t of r){let n=i.get(t),r=n?n[e.field]:void 0;if(r==null||r===``)continue;let s=Number(r);Number.isFinite(s)?a.push({smid:t,val:s}):o.push({smid:t,val:String(r)})}let s=a.length>=o.length&&a.length>0,c=new Map,l=[],u=e.defaultColor??`#64748b`,d=e.nullColor??`#334155`;if(s){let t=a.map(e=>e.val),n=Math.min(...t),r=Math.max(...t)-n||1,i=(e.ramp??[`#3b82f6`,`#10b981`,`#f59e0b`,`#ef4444`]).map(e=>new W(e)),o=Math.max(2,e.stops??5);for(let e=0;e<o;e++){let t=e/o,a=(e+1)/o,s=Nb(i,(t+a)/2),c=n+t*r,u=n+a*r;l.push({color:`#${s.getHexString()}`,label:`${Fb(c)} ~ ${Fb(u)}`,count:0,min:c,max:u})}for(let{smid:e,val:t}of a){let i=Math.min(1,Math.max(0,(t-n)/r)),a=Math.min(o-1,Math.floor(i*o)),s=l[a].color;c.set(e,s),l[a].count++}}else{let t=new Map;for(let{val:e}of o)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];l.push({color:o,label:t,count:a})}let a=new Map(l.map(e=>[e.label,e.color]));for(let{smid:e,val:t}of o)c.set(e,a.get(t)??u)}let f=0;for(let e of r)c.has(e)||(c.set(e,d),f++);return f>0&&l.push({color:d,label:`无数据 / 缺失`,count:f}),this.setThematicColors(c,e.field),{field:e.field,type:s?`continuous`:`discrete`,matched:r.length-f,missing:f,legend:l}}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?Pb(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=Jg(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 t=Mb(e);if(!t)return;let n=e.userData,r=n.geoRef?.pickInfo,i=this.featureStyles.size>0||this.thematicColors.size>0||this.thematicElevation.size>0,a=this.filter,o=this.fieldFilter!=null||a!=null&&((a.include?.length??0)>0||(a.exclude?.length??0)>0||a.predicate!=null);if(!i&&!o||!r||Object.keys(r).length===0){t.userData.uBatchTexActive&&(t.userData.uBatchTexActive.value=0);return}let s=0;for(let e of Object.values(r)){let t=Jg(e);t>s&&(s=t)}let c=Math.max(s+1,1),l=this._meshBatchTextures.get(e);if(!l||l.width<c){let n=new Float32Array(c*2*4),r=new Cu(n,c,2,ci,ei);r.minFilter=Rr,r.magFilter=Rr,l={texture:r,data:n,width:c},this._meshBatchTextures.set(e,l),t.userData.uBatchTex.value=r,t.userData.uBatchTexWidth.value=c}let{data:u,texture:d}=l,f=l.width;for(let e=0;e<f;e++){u[e*4+0]=-1,u[e*4+1]=-1,u[e*4+2]=-1,u[e*4+3]=0;let t=(f+e)*4;u[t+0]=0,u[t+1]=0,u[t+2]=0,u[t+3]=0}let p=!1,m=new Set,h=new Map,g=new Map,_=new Map,v=new Map;for(let[t,i]of Object.entries(r)){let r=Number(t),o=Jg(i);if(o<0||o>=l.width)continue;v.set(o,(v.get(o)??0)+1);let s=!1;if(a&&(a.include&&a.include.length>0&&!a.include.includes(r)&&(s=!0),a.exclude&&a.exclude.length>0&&a.exclude.includes(r)&&(s=!0),a.predicate)){let{segments:t}=Xg(n.geoRef,o),i=Qg({smid:r,box:Zg(e.geometry,t),triangles:0,floorHeight:this._getLayerFloorHeight()});a.predicate({...i,smid:r})||(s=!0)}if(s){m.add(o);continue}if(this.fieldFilter){let e=this.fieldFilter.matched.has(r);if(this.fieldFilter.mode===`keep`?!e:e){m.add(o);continue}}let c=this.featureStyles.get(r);if(c?.hidden){m.add(o);continue}let u=c?.color??this.thematicColors.get(r);u&&!h.has(o)&&h.set(o,u);let d=c?.elevation??this.thematicElevation.get(r);d!=null&&!g.has(o)&&g.set(o,d),c?.translation&&!_.has(o)&&_.set(o,c.translation)}for(let e of m)u[e*4+3]=-1,p=!0;let y=new W;for(let[e,t]of h)m.has(e)||(y.set(t),u[e*4+0]=y.r,u[e*4+1]=y.g,u[e*4+2]=y.b,p=!0);for(let[e,t]of g){if(m.has(e))continue;u[e*4+3]=t;let n=(f+e)*4;u[n+2]=t,p=!0}for(let[e,t]of _){if(m.has(e))continue;let n=(f+e)*4;u[n+0]=t[0],u[n+1]=t[1],u[n+2]=t[2]+(g.get(e)??0),p=!0}let b=0;for(let[e,t]of v)t<2||(m.has(e)||h.has(e)||g.has(e))&&b++;b>0&&!this._batchConflictWarned&&(this._batchConflictWarned=!0,console.warn(`[s3m] 有 ${b} 个单体状态写不进独立的 batch(多个 SMID 共用同一个 batchId,\n S3M 的单体化粒度只到 batch,无法单独隐藏/改色其中一部分)。
4340
4340
  当前规则:任一 SMID 需要隐藏则整批隐藏,颜色 / 抬高取首个。
4341
4341
  用 layer.auditBatches() 可以列出具体是哪些 SMID 共用了 batchId。`)),d.needsUpdate=!0,t.userData.uBatchTexActive&&(t.userData.uBatchTexActive.value=+!!p)}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()}}};rh();var Lb=class{constructor(e={}){X(this,`mode`,void 0),X(this,`opacity`,void 0),X(this,`color`,void 0),X(this,`gridColor`,void 0),X(this,`gridSize`,void 0),X(this,`excavationBounds`,null),X(this,`size`,void 0),X(this,`groundHeight`,0),X(this,`occlude`,void 0),X(this,`trackHeight`,void 0),X(this,`group`,void 0),X(this,`_mesh`,null),X(this,`_material`,null),X(this,`_depthMesh`,null),X(this,`_depthMaterial`,null),X(this,`_geom`,null),X(this,`_occludeExplicit`,void 0),this.mode=e.mode??`none`,this.opacity=e.opacity??.62,this.color=new W(e.color??`#0f172a`),this.gridColor=new W(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 Ml,this.group.name=`s3m-ground-surface`,this._initMesh(),this._applyMode()}_initMesh(){let e=new Pc(this.size,this.size,1,1);this._geom=e;let t=new gc({transparent:!0,depthTest:!0,depthWrite:!1,side:2,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 B(-9999,-9999)},uExcavationMax:{value:new B(9999,9999)}},vertexShader:`
4342
4342
  varying vec2 vEnuPos;
@@ -4416,4 +4416,4 @@ void main() {
4416
4416
  }
4417
4417
  gl_FragColor = vec4(1.0);
4418
4418
  }
4419
- `}),i=new dc(e,r);i.position.set(0,0,-.02),i.renderOrder=-1e3,i.name=`s3m-ground-depth`,i.visible=!1,this.group.add(i),this._depthMesh=i,this._depthMaterial=r,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()}};rh(),dy(),jy(),t_();var Rb=65534;function zb(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function Bb(e){return e.isPoints===!0}var Vb=class e{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={}){X(this,`options`,void 0),X(this,`pickable`,void 0),X(this,`onStats`,void 0),X(this,`onReady`,void 0),X(this,`onPick`,void 0),X(this,`onError`,void 0),X(this,`geo`,null),X(this,`canvas`,null),X(this,`renderer`,null),X(this,`scene`,null),X(this,`camera`,null),X(this,`picker`,null),X(this,`uniforms`,void 0),X(this,`style`,void 0),X(this,`outlineMaterial`,void 0),X(this,`lineShared`,void 0),X(this,`edgeMaterial`,void 0),X(this,`selectionEdgeMaterial`,void 0),X(this,`groundManager`,void 0),X(this,`_datasetManager`,new jb),X(this,`_featureStyleManager`,void 0),X(this,`_pickables`,new Map),X(this,`_pickSeq`,0),X(this,`_freePickIds`,[]),X(this,`_smidMeshes`,new Map),X(this,`_meshHeight`,new Map),X(this,`_heightMin`,1/0),X(this,`_heightMax`,-1/0),X(this,`_boxScratch`,new ho),X(this,`_selection`,null),X(this,`_selectedMeshes`,[]),X(this,`_outlineMesh`,null),X(this,`_outlineMeshes`,[]),X(this,`_selectionEdges`,null),X(this,`_selectionEdgeMeshes`,[]),X(this,`_edgesEnabled`,!1),X(this,`_creaseLines`,null),X(this,`attributeQuery`,null),X(this,`_enuMatrix`,new U),X(this,`_needsRepaint`,!0),X(this,`_frame`,0),X(this,`_fps`,{value:0,last:0}),X(this,`_ambientLight`,void 0),X(this,`_hemiLight`,void 0),X(this,`_keyLight`,void 0),X(this,`_fillLight`,void 0),X(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}),X(this,`_datasetQueue`,void 0),X(this,`_onRequestRepaint`,()=>{}),X(this,`_getBearing`,void 0),X(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 Lb(e.ground),this.scene||(this.scene=new Wl,this.scene.add(this.groundManager.group),this._addLights()),this._featureStyleManager=new Ib(()=>this.style.floorHeight,()=>this._requestRepaint(),()=>{this._selection&&this._syncSelectionStyle()},()=>this.getAllMeshes(),e=>this._applyOverridesToMesh(e)),this.uniforms=fy(),this.style={...yy,...e.style??{}},this.outlineMaterial=my(this.uniforms),this.lineShared=Cb(),this.edgeMaterial=Eb(this.lineShared,{color:this.style.edgeColor,opacity:this.style.edgeOpacity??.45,width:this.style.edgeWidth??1.2}),this.selectionEdgeMaterial=Eb(this.lineShared,{color:this.style.outlineColor??this.style.selectColor,opacity:1,width:this.style.outlineWidthPx??3}),this.setEdges(!!this.style.edges),this._fps.last=performance.now(),this._datasetQueue=this._normalizeDatasets(e),e.attributes&&(this.attributeQuery=new o_(e.attributes))}_createRenderer(e,t){let n=new Vl({canvas:e,context:t,antialias:!0});return n.autoClear=!1,n.setPixelRatio(1),n.toneMapping=4,n.toneMappingExposure=1,n}mount(e,t){this.canvas=e,this.renderer=this._createRenderer(e,t),ty(this.renderer.capabilities.getMaxAnisotropy()),this.scene=new Wl,this.scene.add(this.groundManager.group),this._addLights(),this.camera=new _c,this.camera.matrixAutoUpdate=!1,this.picker=new Sb(this.renderer),this._applyStyleUniforms();for(let e of this._datasetQueue)this.addDataset(e).catch(e=>this.onError(e));this._recomputeAnchors()}restoreContext(e){if(!this.canvas)console.warn(`[s3m] restoreContext 调用过早(尚未 mount),按首次挂载处理`);else{try{this.renderer?.dispose()}catch{}this.renderer=this._createRenderer(this.canvas,e),ty(this.renderer.capabilities.getMaxAnisotropy()),this.picker?.dispose(),this.picker=new Sb(this.renderer),this._requestRepaint()}}unmount(){for(let e of[...this.datasets.keys()])this.removeDataset(e);this.clearCreases(),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 mp(this._lightOptions.ambientColor,this._lightOptions.ambientIntensity),this._hemiLight=new ep(this._lightOptions.hemisphereColor,this._lightOptions.hemisphereGroundColor,this._lightOptions.hemisphereIntensity),this._keyLight=new pp(this._lightOptions.keyLightColor,this._lightOptions.keyLightIntensity),this._fillLight=new pp(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 d_(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 o_(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=zb(t);r&&r.dispose(),gb(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=Bb(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),!n&&!i&&this._datasetEdgesEnabled(t)&&!this._shouldSkipAutoEdges(o,t.name)&&this._ensureEdges(a),i)this._applyPointCloudStyle(r);else{let e=zb(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,t){if(!t.point)return!1;let n=e.geometry;if(!n||(n.boundingBox||n.computeBoundingBox(),!n.boundingBox))return!1;let r=new H(t.point[0],t.point[1],t.point[2]);e.updateWorldMatrix(!0,!1);let i=e.matrixWorld.clone().invert(),a=r.applyMatrix4(i);return n.boundingBox.clone().expandByScalar(.5).containsPoint(a)}_replaySelectionOnto(e){let t=this._selection;if(!t)return;let n=zb(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?Jg(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),Bb(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),zb(t)?.dispose?.()}gb(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>Rb){for(let e=0;e<=Rb;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(),`edgeThreshold`in e&&this._edgesEnabled?this.setEdges(!0):`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:gy[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??_y.OVERLAY;e.uSelMode&&(e.uSelMode.value=n===_y.REPLACE?0:n===_y.MULTIPLY?2:n===_y.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(Bb(r.mesh)){this._applyPointCloudStyle(r.mesh);continue}let i=zb(r.mesh);i&&(i.opacity=e,i.transparent=t,i.depthWrite=!t||n)}this._requestRepaint()}_applyPointCloudStyle(e,t=this._selectedMeshes.includes(e)){hb(e,this.style,this.uniforms,t)}_applyPointCloudStyles(){for(let e of this._pickables.values())Bb(e.mesh)&&this._applyPointCloudStyle(e.mesh);this._requestRepaint()}_applyShading(){let e=this.style.shading!==`smooth`;for(let t of this._pickables.values()){let n=zb(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&&!Bb(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()}async loadCreases(e){let t=await fetch(e);if(!t.ok)throw Error(`[s3m] 棱线缓存加载失败: ${t.status} ${e}`);let n=await t.arrayBuffer(),r=new Float32Array(n);if(r.length<6)return;let i=new q;i.setAttribute(`position`,new G(r,3));let a=this.style,o=new Qu({color:new W(a.edgeColor),transparent:!0,opacity:Math.min(1,Math.max(0,a.edgeOpacity??.6))*Math.min(1,Math.max(.05,a.opacity??1)),depthWrite:!1}),s=new ld(i,o);s.renderOrder=2,s.frustumCulled=!1,s.raycast=()=>{},this.clearCreases(),this._creaseLines=s,this.scene?.add(s),this._requestRepaint()}clearCreases(){this._creaseLines&&(this.scene?.remove(this._creaseLines),this._creaseLines.geometry.dispose(),this._creaseLines.material?.dispose?.(),this._creaseLines=null,this._requestRepaint())}_syncEdgeStyle(){let e=this.style,t=this.edgeMaterial.uniforms;if(t.uColor.value.set(e.edgeColor),t.uWidth.value=Math.max(.1,e.edgeWidth??1.5),t.uOpacity.value=Math.min(1,Math.max(0,e.edgeOpacity??.6))*Math.min(1,Math.max(.05,e.opacity??1)),this._creaseLines){let t=this._creaseLines.material;t.color.set(e.edgeColor),t.opacity=Math.min(1,Math.max(0,e.edgeOpacity??.6))*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??.6)*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)})}_datasetEdgesEnabled(e){let t=e.options?.enableEdges;return t===!0||t!==!1&&this._edgesEnabled}_shouldSkipAutoEdges(t,n){let r=`${t.skeletonName??``} ${n}`.toLowerCase();return e._EDGE_SKIP_KEYWORDS.some(e=>r.includes(e))}_ensureEdges(e){let t=e.userData;if(t.edges||t.nativeEdges||!e.geometry||this._shouldSkipAutoEdges(t,``))return;let n=e.geometry.getAttribute(`position`);if((e.geometry.index?.count??(n?n.count:0))>12e4)return;let r=cb(e.geometry,.005),i=this.style.edgeThreshold??55,a=new Qd(r,i);r.dispose();let o=a.getAttribute(`position`),s=o?o.array:null;if(a.dispose(),!s||s.length<6)return;let c=new dc(Db(s),this.edgeMaterial);c.renderOrder=2,c.frustumCulled=!1,c.raycast=()=>{},c.userData.isThickEdge=!0,t.edges=c,e.add(c)}_removeEdges(e){let t=e.userData,n=t.edges;n&&(e.remove(n),n.geometry?.dispose(),t.edges=null)}getRayAt(e,t){if(!this.camera||!this.canvas)return null;let n=this.canvas,r=n.clientWidth||n.width,i=n.clientHeight||n.height;if(!r||!i)return null;let a=e/r*2-1,o=-(t/i)*2+1,s=new H(a,o,-1).unproject(this.camera),c=new H(a,o,1).unproject(this.camera).clone().sub(s).normalize();return new Bo(s,c)}_intersectMeshAtRay(e,t,n){let r=new gm;r.ray.copy(t);let i=r.intersectObject(e,!1);if(!i.length)return null;if(n!=null){let e=i.find(e=>e.instanceId===n);return e?e.point:i[0].point}return i[0].point}_buildPickResult(e,t,n,r){let i=t.mesh.userData,a=null,o=e.batchId,s=e.instanceIndex,c=i.geoRef,l=[];if(s!=null){let e=this._instanceFeature(t.mesh,c,s);if(!e)return null;a=e.smid,o=e.batchId}else{c=i.geoByBatchId?.get(e.batchId)??i.geoRef;let t=Xg(c,e.batchId);a=t.smid,l=t.segments}if(this._isFeatureHidden(a,o))return null;let u=null,d=0;if(s!=null)u=this._instanceBox(t.mesh,s),d=t.mesh.geometry.index?Math.round(t.mesh.geometry.index.count/3):0;else if(a!=null&&this._smidMeshes.has(a)){let e=this._smidMeshes.get(a),t=1/0,n=1/0,r=1/0,i=-1/0,o=-1/0,s=-1/0,c=0;for(let l of e){let e=l.userData,u=e.geoRef?.pickInfo,f=u?.[a]??u?.[String(a)],p=f?Jg(f):-1,m=f?.segments??(p>=0?Xg(e.geoRef,p).segments:[]),h=Zg(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>o&&(o=h.maxY),h.maxZ>s&&(s=h.maxZ),c+=h.count,d+=h.triangles)}c>0&&(u={minX:t,minY:n,minZ:r,maxX:i,maxY:o,maxZ:s,count:c,triangles:d})}if(!u&&(u=Zg(t.mesh.geometry,l),!u&&t.mesh.geometry)){t.mesh.geometry.boundingBox||t.mesh.geometry.computeBoundingBox();let e=t.mesh.geometry.boundingBox;e&&(u={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 f=t.mesh.geometry,p=d>0?d:f.index?Math.round(f.index.count/3):0,m=Qg({smid:a,box:u,triangles:p,floorHeight:this.style.floorHeight}),h=null;if(u&&this.sceneAnchor){let e=new H((u.minX+u.maxX)/2,(u.minY+u.maxY)/2,(u.minZ+u.maxZ)/2);e.applyMatrix4(t.mesh.matrixWorld);let n=this.sceneAnchor.meterInMercator;h=this._lngLatFromWorld(e.x*n+this.sceneAnchor.x,-e.y*n+this.sceneAnchor.y)}let g=n??null;!g&&r&&(g=this._intersectMeshAtRay(t.mesh,r,s));let _=null,v=null,y=null;if(g&&this.sceneAnchor){let e=a==null?{}:this._featureStyleManager.getFeatureEffectiveOffset(a),t=e.translation,n=e.elevation,r=g.clone();t?r.add(new H(t[0],t[1],t[2])):n&&(r.z+=n),_=[r.x,r.y,r.z];let i=this.sceneAnchor.meterInMercator;v=this._lngLatFromWorld(r.x*i+this.sceneAnchor.x,-r.y*i+this.sceneAnchor.y),y=r.z+(this.sceneAnchor.altitude??0)}else h&&u&&this.sceneAnchor&&(v=h,y=(u.minZ+u.maxZ)/2+(this.sceneAnchor.altitude??0));return{datasetId:t.datasetId,datasetName:this.datasets.get(t.datasetId)?.name??t.datasetId,objectId:e.objectId,batchId:o,instanceIndex:s,skeletonName:t.skeletonName,centerLngLat:h,point:_,lngLat:v,altitude:y,...m,mesh:t.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,t){if(!this.camera||!this.sceneAnchor)return null;let n=this.pick(e,t);if(n?.point&&n?.lngLat&&n.altitude!=null)return{lngLat:n.lngLat,altitude:n.altitude,point:n.point};let r=this.getRayAt(e,t);if(!r)return null;let i=new Ac(new H(0,0,1),0),a=new H,o=r.intersectPlane(i,a);if(o){let e=this.sceneAnchor.meterInMercator;return{lngLat:this._lngLatFromWorld(o.x*e+this.sceneAnchor.x,-o.y*e+this.sceneAnchor.y),altitude:o.z+(this.sceneAnchor.altitude??0),point:[o.x,o.y,o.z]}}return null}drillPick(e,t,n=10){if(!this.sceneAnchor||!this.camera)return[];let r=this.getRayAt(e,t);if(!r)return[];let i=new gm;i.ray.copy(r);let a=[...this._pickables.values()].map(e=>e.mesh).filter(e=>{let t=e;for(;t;){if(!t.visible)return!1;t=t.parent}return!0}),o=i.intersectObjects(a,!1);if(!o.length)return[];let s=[],c=new Set,l=new Set;for(let e of o){if(s.length>=n)break;let t=e.object,r=t.userData;if(r.pickId==null)continue;let i=this._pickables.get(r.pickId);if(!i)continue;let a=null,o=-1,u=e.instanceId;if(u!=null){let e=this._instanceFeature(t,r.geoRef,u);if(!e)continue;a=e.smid,o=e.batchId}else if(e.faceIndex!=null){let n=t.geometry.attributes.aBatchId;if(n){let i=t.geometry.index?t.geometry.index.getX(e.faceIndex*3):e.faceIndex*3;o=Math.round(n.getX(i)),a=Xg(r.geoByBatchId?.get(o)??r.geoRef,o).smid}}if(a!=null){if(c.has(a))continue;c.add(a)}else{let e=`${r.pickId}:${o}:${u??-1}`;if(l.has(e))continue;l.add(e)}if(this._isFeatureHidden(a,o))continue;let d={objectId:r.pickId,batchId:o,instanceIndex:u},f=this._buildPickResult(d,i,e.point);f&&s.push(f)}return s}getFeatureBounds(e){if(!this.sceneAnchor)return null;let t=1/0,n=-1/0,r=1/0,i=-1/0,a=!1;for(let o of this._pickables.values()){let s=o.mesh,c=s.userData,l=c.geoRef,u=l?.pickInfo;if(!u)continue;let d=null;if(s.isInstancedMesh){let t=c.instanceLookup;t||(t=Yg(u),c.instanceLookup=t);for(let[n,r]of t)if(r.smid===e){d=this._instanceBox(s,n);break}}else{let t=u,n=t[e]??t[String(e)];if(n){let e=Xg(l,Jg(n));if(d=Zg(s.geometry,e.segments),!d&&s.geometry){s.geometry.boundingBox||s.geometry.computeBoundingBox();let e=s.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})}}}if(d){a=!0;let o=[new H(d.minX,d.minY,d.minZ),new H(d.maxX,d.minY,d.minZ),new H(d.minX,d.maxY,d.minZ),new H(d.maxX,d.maxY,d.minZ),new H(d.minX,d.minY,d.maxZ),new H(d.maxX,d.minY,d.maxZ),new H(d.minX,d.maxY,d.maxZ),new H(d.maxX,d.maxY,d.maxZ)],c=e==null?{}:this._featureStyleManager.getFeatureEffectiveOffset(e),l=c.translation,u=c.elevation;for(let e of o){l?e.add(new H(l[0],l[1],l[2])):u&&(e.z+=u),e.applyMatrix4(s.matrixWorld);let a=this.sceneAnchor.meterInMercator,[o,c]=this._lngLatFromWorld(e.x*a+this.sceneAnchor.x,-e.y*a+this.sceneAnchor.y);o<t&&(t=o),o>n&&(n=o),c<r&&(r=c),c>i&&(i=c)}}}return a?[[t,r],[n,i]]:null}_instanceFeature(e,t,n){let r=e.userData;return r.instanceLookup||(r.instanceLookup=Yg(t?.pickInfo)),r.instanceLookup.get(n)??null}_instanceBox(e,t){let n=e;if(!n.isInstancedMesh)return null;let r=e.geometry;r.boundingBox||r.computeBoundingBox();let i=r.boundingBox;if(!i)return null;let a=new U;n.getMatrixAt(t,a);let o=i.clone().applyMatrix4(a);return{minX:o.min.x,minY:o.min.y,minZ:o.min.z,maxX:o.max.x,maxY:o.max.y,maxZ:o.max.z,count:r.getAttribute(`position`)?.count??0,triangles:r.index?Math.round(r.index.count/3):0}}select(e,{silent:t=!1}={}){if(this._selection){for(let e of this._selectedMeshes){if(Bb(e)){this._applyPointCloudStyle(e,!1);continue}let t=zb(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=zb(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?Jg(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)Bb(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=>!Bb(e));t.length&&((this.style.outlineStyle??`edges`)===`edges`?this._addSelectionEdges(e,t):this._addSelectionHull(e,t))}this._requestRepaint()}_addSelectionEdges(e,t){this._syncSelectionStyle();for(let n of t){let t=n.userData,r=t.geoRef,i=[];if(n===e.mesh&&e.instanceIndex!=null)i=[{vertexOffset:0,vertexCount:n.geometry.getAttribute(`position`)?.count??0}];else if(e.smid!=null){let t=r?.pickInfo,n=t?.[e.smid]??t?.[String(e.smid)],a=n?Jg(n):-1;i=n?.segments??(a>=0?Xg(r,a).segments:[])}else n===e.mesh&&(i=Xg(t.geoByBatchId?.get(e.batchId)??r,e.batchId).segments);let a=Ab(n.geometry,i);if(a&&a.length>0){let t=new dc(Db(a),this.selectionEdgeMaterial);t.renderOrder=4,t.frustumCulled=!1,t.raycast=()=>{},t.userData.isSelectionEdge=!0,n===e.mesh&&e.instanceIndex!=null&&this._applyInstanceTransform(t,e),n.add(t),this._selectionEdgeMeshes.push(t)}}this._selectionEdgeMeshes.length===0?this._addSelectionHull(e,t):this._selectionEdges=this._selectionEdgeMeshes[0]??null}_applyInstanceTransform(e,t){let n=t.mesh;if(t.instanceIndex==null||!n.isInstancedMesh)return;let r=new U;n.getMatrixAt(t.instanceIndex,r),r.decompose(e.position,e.quaternion,e.scale)}_addSelectionHull(e,t){let n=e.instanceIndex!=null;this.outlineMaterial.uniforms.uSelBatch.value=n?-1:e.batchId,this.outlineMaterial.uniforms.uSelWhole.value=n||e.batchId<0?1:0,this.outlineMaterial.uniforms.uElevation.value=n?this._selectionElevation(e):this.style.selectElevation??0;for(let n of t){let t=zb(n);t?.userData?.uBatchTex&&(this.outlineMaterial.uniforms.uBatchTex.value=t.userData.uBatchTex.value,this.outlineMaterial.uniforms.uBatchTexWidth.value=t.userData.uBatchTexWidth.value,this.outlineMaterial.uniforms.uBatchTexActive.value=t.userData.uBatchTexActive.value);let r=new dc(n.geometry,this.outlineMaterial);r.renderOrder=3,r.frustumCulled=!1,r.raycast=()=>{},n===e.mesh&&e.instanceIndex!=null&&this._applyInstanceTransform(r,e),n.add(r),this._outlineMeshes.push(r)}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?zb(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;let t=this.renderer.getContext();if(t&&typeof t.isContextLost==`function`&&t.isContextLost())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 U().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===hy.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===hy.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=ib(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()}};X(Vb,`_EDGE_SKIP_KEYWORDS`,[`terrain`,`ground`,`vegetation`,`green`,`road`,`dem`,`绿地`,`道路`,`地面`,`地形`,`植被`,`铺装`]),rh();var Hb=1e-4;function Ub(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])>Hb*r)return!1}return!0}function Wb(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 Gb(e,t){return t>0&&Math.abs(e.elements[5]*Math.tan(t/2)-1)<.001}function Kb(e){if(!e||typeof e!=`object`)return null;let t=e;return t.defaultProjectionData?.projectionMatrix??t.projectionMatrix??null}function qb(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 Jb(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 Yb(e,t){let n=e.projectionMatrix;if(!n||n.length<16)return null;let r=new U().fromArray(Array.from(n)),i=new U().fromArray(Array.from(e.mvp));if(r.determinant()===0||!Gb(r,t.fov))return null;let a=r.clone().invert().multiply(i);if(!Ub(r.clone().multiply(a),Array.from(e.mvp))||!Wb(a)||!Gb(r,t.fov))return null;let{distance:o,fov:s,aspect:c}=t;if(!(o>0)||!(s>0)||!(c>0))return null;let l=o*Math.tan(s/2),u=l*c,d=e.nearZ!=null&&e.nearZ>0?e.nearZ:1,f=e.farZ!=null&&e.farZ>d?e.farZ:o*4+1e3;f>d||(f=d+1e3);let p=new zc(-u,u,l,-l,d,f);return p.updateProjectionMatrix(),{matrix:p.projectionMatrix.clone().multiply(a),view:a}}var Xb=.6435011087932844;function Zb(e){let t=e,n=t?.transform?.worldCoordinateHelper??t?.transform?.projection?.worldCoordinateHelper??t?.painter?.transform?.worldCoordinateHelper??(typeof t?.getProjection==`function`?t.getProjection()?.worldCoordinateHelper:null)??null;return n&&typeof n.worldFromLngLat==`function`&&typeof n.lngLatFromWorld==`function`?n:null}function Qb(e){let t=Zb(e);return t?{worldFromLngLat(e,n,r=0){let i=t.worldFromLngLat(e,n,r),a=0;if(typeof t.metersPerWorldUnit==`function`){let e=t.metersPerWorldUnit(i.x,i.y);Number.isFinite(e)&&e>0&&(a=1/e)}if(a===0){let o=t.worldFromLngLat(e,n,r+1),s=Math.abs((o.z??0)-(i.z??0));Math.sin(n*Math.PI/180),a=s>0?s:1/(2*Math.PI*6378137)/Math.cos(n*Math.PI/180)}return{x:i.x,y:i.y,z:i.z??r*a,meterInMercator:a,altitude:r}},lngLatFromWorld(e,n){let r=t.lngLatFromWorld(e,n);return Array.isArray(r)?[r[0],r[1]]:r&&typeof r.lng==`number`&&typeof r.lat==`number`?[r.lng,r.lat]:[0,0]}}:null}rh();var $b=class{get map(){return this._map}set map(e){this._map=e,this.viewer.geo=e?Qb(e):null}_mapGl(){let e=this.map?.getCanvas?.();return e?e.getContext(`webgl2`)??e.getContext(`webgl`):null}constructor(e={}){X(this,`id`,void 0),X(this,`type`,`custom`),X(this,`renderingMode`,`3d`),X(this,`options`,void 0),X(this,`pickable`,void 0),X(this,`onStats`,void 0),X(this,`onReady`,void 0),X(this,`onPick`,void 0),X(this,`onError`,void 0),X(this,`_map`,null),X(this,`viewer`,void 0),X(this,`_orthoWarned`,!1),X(this,`_projection`,`perspective`),X(this,`_onProjectionChange`,()=>{this.map&&(this.viewer.geo=Qb(this.map)),this.viewer.recomputeAnchors()}),X(this,`_contextLost`,!1),X(this,`_listenersAttached`,!1),X(this,`_onContextLost`,()=>{this._contextLost=!0}),X(this,`_onContextRestored`,()=>{this._contextLost=!1;let e=this.map;if(e){try{let t=e.getLayer,n=e.addLayer;if(!(typeof t==`function`&&t.call(e,this.id)))typeof n==`function`&&n.call(e,this);else{let e=this._mapGl();e&&this.viewer.restoreContext(e)}}catch(e){console.warn(`[s3m] WebGL 上下文恢复后重加图层失败,请手动 map.addLayer(layer)`,e)}e.triggerRepaint()}}),X(this,`_onClick`,e=>{if(!this.pickable)return;let t=this.pickFromEvent(e);t?(this.select(t),this.onPick(t)):this.select(null)}),this.id=e.id??`s3m`,this.options=e,this.pickable=e.pickable!==!1,this._projection=e.projection===`orthographic`?`orthographic`:`perspective`,this.onStats=e.onStats??(()=>{}),this.onReady=e.onReady??(()=>{}),this.onPick=e.onPick??(()=>{}),this.onError=e.onError??(e=>console.warn(`[s3m]`,e)),this.viewer=new Vb({configUrl:e.configUrl,datasets:e.datasets,style:e.style,ground:e.ground,pickable:e.pickable,maxTiles:e.maxTiles,maxConcurrent:e.maxConcurrent,lodRangeScale:e.lodRangeScale,buildTile:e.buildTile,light:e.light,totalMaxTiles:e.totalMaxTiles,attributes:e.attributes,onRequestRepaint:()=>this.map?.triggerRepaint(),getBearing:()=>this.map?.getBearing?.()??0,onStats:e=>this.onStats(e),onReady:e=>this.onReady(e),onPick:e=>this.onPick(e),onError:e=>this.onError(e)})}onAdd(e,t){this.map=e,this.viewer.renderer?this.viewer.restoreContext(t):this.viewer.mount(e.getCanvas(),t),this._listenersAttached||(e.on(`click`,this._onClick),typeof e.on==`function`&&(e.on(`projectiontransition`,this._onProjectionChange),e.on(`webglcontextlost`,this._onContextLost),e.on(`webglcontextrestored`,this._onContextRestored)),this._listenersAttached=!0)}onRemove(){this.map?.off(`click`,this._onClick),typeof this.map?.off==`function`&&(this.map.off(`projectiontransition`,this._onProjectionChange),this.map.off(`webglcontextlost`,this._onContextLost),this.map.off(`webglcontextrestored`,this._onContextRestored)),this._listenersAttached=!1,this._contextLost=!1,this.viewer.unmount(),this.viewer.geo=null,this.map=null}_extractMatrix(e){if(Array.isArray(e)||e instanceof Float64Array||e instanceof Float32Array)return e;let t=e;return t?.defaultProjectionData?.mainMatrix??t?.modelViewProjectionMatrix??null}_applyOrtho(e,t){let{nearZ:n,farZ:r}=qb(e),i=Kb(e);if(!i)return this._warnOrtho(`render() 输入里没有独立的投影矩阵(需要 MapLibre ≥ 5)`),null;let a=Yb({projectionMatrix:i,mvp:t.elements,nearZ:n,farZ:r},{distance:this.map?.transform?.cameraToCenterDistance??0,fov:this._frameFov(e),aspect:this._canvasAspect()});return a?a.matrix:(this._warnOrtho(`拿到的投影矩阵与 MVP 不同源(反推结果不是仿射变换)`),null)}_warnOrtho(e){this._orthoWarned||(this._orthoWarned=!0,console.warn(`[s3m] 正交模式不可用:${e},本帧保持透视`))}_frameFov(e){return Jb(e,this.map?.transform?.fovInRadians)??.6435011087932844}_canvasAspect(){let e=this.map?.getCanvas?.();return!e||!e.height?1:e.width/e.height}setProjection(e){let t=e===`orthographic`?`orthographic`:`perspective`;this._projection!==t&&(this._projection=t,this._orthoWarned=!1,this.map?.triggerRepaint())}get projection(){return this._projection}render(e,t){let n=this.map,r=this.viewer.sceneAnchor;if(!n||!r||this._contextLost)return;let i=this._extractMatrix(t);if(!i)return;let a=new U().fromArray(i);this._projection===`orthographic`&&(a=this._applyOrtho(t,a)??a);let o=n.getCanvas(),s=r.meterInMercator,c=[0,0,0];try{let e=n.getFreeCameraOptions?.()?.position;e&&(c=[(e.x-r.x)/s,-(e.y-r.y)/s,(e.z-r.z)/s])}catch{}this.viewer.renderFrame({mvp:a.elements,cameraEnu:c,fovRad:this._frameFov(t),canvasHeight:o.height})&&n.triggerRepaint()}pickFromEvent(e){let t=this.map?.getCanvas();if(!t)return null;let n=t.getBoundingClientRect(),r=e.originalEvent??e;return this.viewer.pick(r.clientX-n.left,r.clientY-n.top)}pick(e,t){return this.viewer.pick(e,t)}pickPosition(e,t){return this.viewer.pickPosition(e,t)}drillPick(e,t,n=10){return this.viewer.drillPick(e,t,n)}getRayAt(e,t){return this.viewer.getRayAt(e,t)}select(e,t={}){this.viewer.select(e,t)}getFeatureBounds(e){return this.viewer.getFeatureBounds(e)}flyToFeature(e,t){let n=this.viewer.getFeatureBounds(e);if(!n||!this.map)return!1;let r=this.map;return typeof r.fitBounds==`function`&&(r.fitBounds(n,{padding:50,maxZoom:19,duration:1200,...t}),!0)}addDataset(e){return this.viewer.addDataset(e)}removeDataset(e){this.viewer.removeDataset(e)}clearDatasets(){this.viewer.clearDatasets()}setDatasetVisible(e,t){this.viewer.setDatasetVisible(e,t)}getDatasetHeight(e){return this.viewer.getDatasetHeight(e)}setDatasetHeight(e,t){this.viewer.setDatasetHeight(e,t)}setDatasetAlign(e,t){this.viewer.setDatasetAlign(e,t)}_computeAlignOffset(e,t){return this.viewer.computeAlignOffset(e,t)}setLight(e){this.viewer.setLight(e)}getLight(){return this.viewer.getLight()}setOpacity(e){this.viewer.setOpacity(e)}setStyle(e={}){this.viewer.setStyle(e)}getStyle(){return this.viewer.getStyle()}setEdges(e){this.viewer.setEdges(e)}loadCreases(e){return this.viewer.loadCreases(e)}clearCreases(){this.viewer.clearCreases()}setFeatureStyle(e,t){this.viewer.setFeatureStyle(e,t)}setFeaturesStyle(e,t){this.viewer.setFeaturesStyle(e,t)}getFeatureStyle(e){return this.viewer.getFeatureStyle(e)}getFeatureStyles(){return this.viewer.getFeatureStyles()}removeFeatureStyle(e){this.viewer.removeFeatureStyle(e)}clearFeatureStyles(){this.viewer.clearFeatureStyles()}setAttributeSource(e){this.viewer.setAttributeSource(e)}getLoadedSmids(){return this.viewer.getLoadedSmids()}auditBatches(){return this.viewer.auditBatches()}getThematicField(){return this.viewer.getThematicField()}setThematicColors(e,t=`custom`){this.viewer.setThematicColors(e,t)}clearThematic(){this.viewer.clearThematic()}getFilterField(){return this.viewer.getFilterField()}filterByField(e){return this.viewer.filterByField(e)}clearFieldFilter(){this.viewer.clearFieldFilter()}getElevationField(){return this.viewer.getElevationField()}elevateByField(e){return this.viewer.elevateByField(e)}setThematicElevation(e,t=`custom`){this.viewer.setThematicElevation(e,t)}clearThematicElevation(){this.viewer.clearThematicElevation()}colorByField(e){return this.viewer.colorByField(e)}setFilter(e){this.viewer.setFilter(e)}getFilter(){return this.viewer.getFilter()}clearFilter(){this.viewer.clearFilter()}setGroundMode(e){this.viewer.setGroundMode(e)}setGroundOpacity(e){this.viewer.setGroundOpacity(e)}setExcavationBounds(e){this.viewer.setExcavationBounds(e)}setGroundOcclude(e){this.viewer.setGroundOcclude(e)}get groundManager(){return this.viewer.groundManager}getAllMeshes(){return this.viewer.getAllMeshes()}flushOverrides(){this.viewer.flushOverrides()}_applyOverridesToMesh(e){this.viewer._applyOverridesToMesh(e)}get lodRangeScale(){return this.viewer.lodRangeScale}setLodRangeScale(e,t){this.viewer.setLodRangeScale(e,t)}get renderer(){return this.viewer.renderer}get scene(){return this.viewer.scene}get camera(){return this.viewer.camera}get picker(){return this.viewer.picker}get uniforms(){return this.viewer.uniforms}get style(){return this.viewer.style}get outlineMaterial(){return this.viewer.outlineMaterial}get lineShared(){return this.viewer.lineShared}get edgeMaterial(){return this.viewer.edgeMaterial}get selectionEdgeMaterial(){return this.viewer.selectionEdgeMaterial}get datasets(){return this.viewer.datasets}get sceneAnchor(){return this.viewer.sceneAnchor}set sceneAnchor(e){this.viewer.sceneAnchor=e}get attributeQuery(){return this.viewer.attributeQuery}get fps(){return this.viewer.fps}get stats(){return this.viewer.stats}getBounds(){return this.viewer.getBounds()}dispose(){this.onRemove()}},ex=i({AttributeQuery:()=>o_,BinaryReader:()=>sh,DEFAULT_FLOOR_HEIGHT:()=>e_,DEFAULT_FOV:()=>Xb,DEFAULT_STYLE:()=>yy,DatasetManager:()=>jb,EARTH_RADIUS:()=>s_,FeatureStyleManager:()=>Ib,GroundManager:()=>Lb,Picker:()=>Sb,PixelFormat:()=>ly,S3MFormatError:()=>Kg,S3MLayer:()=>$b,S3MTileset:()=>sb,S3MViewer:()=>Vb,S3M_VERSION:()=>mg,SELECT_MODE:()=>_y,SELECT_MODE_LABELS:()=>vy,STYLE:()=>hy,STYLE_LABELS:()=>gy,TextureCompress:()=>J_,VertexTag:()=>hg,VertexTagV3:()=>gg,buildAttributes:()=>Qg,buildFeatureEdgeSegments:()=>Ab,buildOrthoMVP:()=>Yb,buildThickLineGeometry:()=>Db,buildTileObjects:()=>Jy,createLineSharedUniforms:()=>Cb,createMapLibreGeoAdapter:()=>Qb,createOutlineMaterial:()=>my,createSharedUniforms:()=>fy,createStyledMaterial:()=>py,createTexture:()=>cy,createThickLineMaterial:()=>Eb,default:()=>$b,dxtPixelFormatOf:()=>q_,extractFovRadians:()=>Jb,extractNearFar:()=>qb,extractProjectionMatrix:()=>Kb,extractWorldCoordinateHelper:()=>Zb,isS3M1Buffer:()=>tg,lngLatFromMercator:()=>l_,lngLatFromWorld:()=>d_,measureSegments:()=>Zg,mercatorFromLngLat:()=>c_,parseS3M1:()=>pg,parseS3MB:()=>qg,resolveFeature:()=>Xg,resolveTextureKind:()=>K_,setMaxAnisotropy:()=>ty,worldFromLngLat:()=>u_});rh(),t_(),Z_(),dy(),jy(),Zy();var tx=globalThis;return tx.THREE||(tx.THREE=a),tx.S3MMapLibre=ex,e.AttributeQuery=o_,e.BinaryReader=sh,e.DEFAULT_FLOOR_HEIGHT=e_,e.DEFAULT_FOV=Xb,e.DEFAULT_STYLE=yy,e.DatasetManager=jb,e.EARTH_RADIUS=s_,e.FeatureStyleManager=Ib,e.GroundManager=Lb,e.Picker=Sb,e.PixelFormat=ly,e.S3MFormatError=Kg,e.S3MLayer=$b,e.default=$b,e.S3MTileset=sb,e.S3MViewer=Vb,e.S3M_VERSION=mg,e.SELECT_MODE=_y,e.SELECT_MODE_LABELS=vy,e.STYLE=hy,e.STYLE_LABELS=gy,e.TextureCompress=J_,e.VertexTag=hg,e.VertexTagV3=gg,e.buildAttributes=Qg,e.buildFeatureEdgeSegments=Ab,e.buildOrthoMVP=Yb,e.buildThickLineGeometry=Db,e.buildTileObjects=Jy,e.createLineSharedUniforms=Cb,e.createMapLibreGeoAdapter=Qb,e.createOutlineMaterial=my,e.createSharedUniforms=fy,e.createStyledMaterial=py,e.createTexture=cy,e.createThickLineMaterial=Eb,e.dxtPixelFormatOf=q_,e.extractFovRadians=Jb,e.extractNearFar=qb,e.extractProjectionMatrix=Kb,e.extractWorldCoordinateHelper=Zb,e.isS3M1Buffer=tg,e.lngLatFromMercator=l_,e.lngLatFromWorld=d_,e.measureSegments=Zg,e.mercatorFromLngLat=c_,e.parseS3M1=pg,e.parseS3MB=qg,e.resolveFeature=Xg,e.resolveTextureKind=K_,e.setMaxAnisotropy=ty,e.worldFromLngLat=u_,e})({});
4419
+ `}),i=new dc(e,r);i.position.set(0,0,-.02),i.renderOrder=-1e3,i.name=`s3m-ground-depth`,i.visible=!1,this.group.add(i),this._depthMesh=i,this._depthMaterial=r,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()}};rh(),dy(),jy(),t_();var Rb=65534;function zb(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function Bb(e){return e.isPoints===!0}var Vb=class e{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={}){X(this,`options`,void 0),X(this,`pickable`,void 0),X(this,`onStats`,void 0),X(this,`onReady`,void 0),X(this,`onPick`,void 0),X(this,`onError`,void 0),X(this,`geo`,null),X(this,`canvas`,null),X(this,`renderer`,null),X(this,`scene`,null),X(this,`camera`,null),X(this,`picker`,null),X(this,`uniforms`,void 0),X(this,`style`,void 0),X(this,`outlineMaterial`,void 0),X(this,`lineShared`,void 0),X(this,`edgeMaterial`,void 0),X(this,`selectionEdgeMaterial`,void 0),X(this,`groundManager`,void 0),X(this,`_datasetManager`,new jb),X(this,`_featureStyleManager`,void 0),X(this,`_pickables`,new Map),X(this,`_pickSeq`,0),X(this,`_freePickIds`,[]),X(this,`_smidMeshes`,new Map),X(this,`_meshHeight`,new Map),X(this,`_heightMin`,1/0),X(this,`_heightMax`,-1/0),X(this,`_boxScratch`,new ho),X(this,`_selection`,null),X(this,`_selectedMeshes`,[]),X(this,`_outlineMesh`,null),X(this,`_outlineMeshes`,[]),X(this,`_selectionEdges`,null),X(this,`_selectionEdgeMeshes`,[]),X(this,`_edgesEnabled`,!1),X(this,`_creaseLines`,null),X(this,`attributeQuery`,null),X(this,`_enuMatrix`,new U),X(this,`_needsRepaint`,!0),X(this,`_frame`,0),X(this,`_fps`,{value:0,last:0}),X(this,`_ambientLight`,void 0),X(this,`_hemiLight`,void 0),X(this,`_keyLight`,void 0),X(this,`_fillLight`,void 0),X(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}),X(this,`_datasetQueue`,void 0),X(this,`_onRequestRepaint`,()=>{}),X(this,`_getBearing`,void 0),X(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 Lb(e.ground),this.scene||(this.scene=new Wl,this.scene.add(this.groundManager.group),this._addLights()),this._featureStyleManager=new Ib(()=>this.style.floorHeight,()=>this._requestRepaint(),()=>{this._selection&&this._syncSelectionStyle()},()=>this.getAllMeshes(),e=>this._applyOverridesToMesh(e)),this.uniforms=fy(),this.style={...yy,...e.style??{}},this.outlineMaterial=my(this.uniforms),this.lineShared=Sb(),this.edgeMaterial=Tb(this.lineShared,{color:this.style.edgeColor,opacity:this.style.edgeOpacity??.45,width:this.style.edgeWidth??1.2}),this.selectionEdgeMaterial=Tb(this.lineShared,{color:this.style.outlineColor??this.style.selectColor,opacity:1,width:this.style.outlineWidthPx??3}),this.setEdges(!!this.style.edges),this._fps.last=performance.now(),this._datasetQueue=this._normalizeDatasets(e),e.attributes&&(this.attributeQuery=new o_(e.attributes))}_createRenderer(e,t){let n=new Vl({canvas:e,context:t,antialias:!0});return n.autoClear=!1,n.setPixelRatio(1),n.toneMapping=4,n.toneMappingExposure=1,n}mount(e,t){this.canvas=e,this.renderer=this._createRenderer(e,t),ty(this.renderer.capabilities.getMaxAnisotropy()),this.scene=new Wl,this.scene.add(this.groundManager.group),this._addLights(),this.camera=new _c,this.camera.matrixAutoUpdate=!1,this.picker=new xb(this.renderer),this._applyStyleUniforms();for(let e of this._datasetQueue)this.addDataset(e).catch(e=>this.onError(e));this._recomputeAnchors()}restoreContext(e){if(!this.canvas)console.warn(`[s3m] restoreContext 调用过早(尚未 mount),按首次挂载处理`);else{try{this.renderer?.dispose()}catch{}this.renderer=this._createRenderer(this.canvas,e),ty(this.renderer.capabilities.getMaxAnisotropy()),this.picker?.dispose(),this.picker=new xb(this.renderer),this._requestRepaint()}}unmount(){for(let e of[...this.datasets.keys()])this.removeDataset(e);this.clearCreases(),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 mp(this._lightOptions.ambientColor,this._lightOptions.ambientIntensity),this._hemiLight=new ep(this._lightOptions.hemisphereColor,this._lightOptions.hemisphereGroundColor,this._lightOptions.hemisphereIntensity),this._keyLight=new pp(this._lightOptions.keyLightColor,this._lightOptions.keyLightIntensity),this._fillLight=new pp(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 d_(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 o_(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=zb(t);r&&r.dispose(),hb(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=Bb(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),!n&&!i&&this._datasetEdgesEnabled(t)&&!this._shouldSkipAutoEdges(o,t.name)&&this._ensureEdges(a),i)this._applyPointCloudStyle(r);else{let e=zb(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,t){if(!t.point)return!1;let n=e.geometry;if(!n||(n.boundingBox||n.computeBoundingBox(),!n.boundingBox))return!1;let r=new H(t.point[0],t.point[1],t.point[2]);e.updateWorldMatrix(!0,!1);let i=e.matrixWorld.clone().invert(),a=r.applyMatrix4(i);return n.boundingBox.clone().expandByScalar(.5).containsPoint(a)}_replaySelectionOnto(e){let t=this._selection;if(!t)return;let n=zb(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?Jg(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),Bb(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),zb(t)?.dispose?.()}hb(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>Rb){for(let e=0;e<=Rb;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(),`edgeThreshold`in e&&this._edgesEnabled?this.setEdges(!0):`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:gy[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??_y.OVERLAY;e.uSelMode&&(e.uSelMode.value=n===_y.REPLACE?0:n===_y.MULTIPLY?2:n===_y.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(Bb(r.mesh)){this._applyPointCloudStyle(r.mesh);continue}let i=zb(r.mesh);i&&(i.opacity=e,i.transparent=t,i.depthWrite=!t||n)}this._requestRepaint()}_applyPointCloudStyle(e,t=this._selectedMeshes.includes(e)){mb(e,this.style,this.uniforms,t)}_applyPointCloudStyles(){for(let e of this._pickables.values())Bb(e.mesh)&&this._applyPointCloudStyle(e.mesh);this._requestRepaint()}_applyShading(){let e=this.style.shading!==`smooth`;for(let t of this._pickables.values()){let n=zb(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&&!Bb(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()}async loadCreases(e){let t=await fetch(e);if(!t.ok)throw Error(`[s3m] 棱线缓存加载失败: ${t.status} ${e}`);let n=await t.arrayBuffer(),r=new Float32Array(n);if(r.length<6)return;let i=new q;i.setAttribute(`position`,new G(r,3));let a=this.style,o=new Qu({color:new W(a.edgeColor),transparent:!0,opacity:Math.min(1,Math.max(0,a.edgeOpacity??.6))*Math.min(1,Math.max(.05,a.opacity??1)),depthWrite:!1}),s=new ld(i,o);s.renderOrder=2,s.frustumCulled=!1,s.raycast=()=>{},this.clearCreases(),this._creaseLines=s,this.scene?.add(s),this._requestRepaint()}clearCreases(){this._creaseLines&&(this.scene?.remove(this._creaseLines),this._creaseLines.geometry.dispose(),this._creaseLines.material?.dispose?.(),this._creaseLines=null,this._requestRepaint())}_syncEdgeStyle(){let e=this.style,t=this.edgeMaterial.uniforms;if(t.uColor.value.set(e.edgeColor),t.uWidth.value=Math.max(.1,e.edgeWidth??1.5),t.uOpacity.value=Math.min(1,Math.max(0,e.edgeOpacity??.6))*Math.min(1,Math.max(.05,e.opacity??1)),this._creaseLines){let t=this._creaseLines.material;t.color.set(e.edgeColor),t.opacity=Math.min(1,Math.max(0,e.edgeOpacity??.6))*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??.6)*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)})}_datasetEdgesEnabled(e){let t=e.options?.enableEdges;return t===!0||t!==!1&&this._edgesEnabled}_shouldSkipAutoEdges(t,n){let r=`${t.skeletonName??``} ${n}`.toLowerCase();return e._EDGE_SKIP_KEYWORDS.some(e=>r.includes(e))}_ensureEdges(e){let t=e.userData;if(t.edges||t.nativeEdges||!e.geometry||this._shouldSkipAutoEdges(t,``))return;let n=e.geometry.getAttribute(`position`);if((e.geometry.index?.count??(n?n.count:0))>12e4)return;let r=Ab(e.geometry,.005),i=this.style.edgeThreshold??55,a=new Qd(r,i);r.dispose();let o=a.getAttribute(`position`),s=o?o.array:null;if(a.dispose(),!s||s.length<6)return;let c=new dc(Eb(s),this.edgeMaterial);c.renderOrder=2,c.frustumCulled=!1,c.raycast=()=>{},c.userData.isThickEdge=!0,t.edges=c,e.add(c)}_removeEdges(e){let t=e.userData,n=t.edges;n&&(e.remove(n),n.geometry?.dispose(),t.edges=null)}getRayAt(e,t){if(!this.camera||!this.canvas)return null;let n=this.canvas,r=n.clientWidth||n.width,i=n.clientHeight||n.height;if(!r||!i)return null;let a=e/r*2-1,o=-(t/i)*2+1,s=new H(a,o,-1).unproject(this.camera),c=new H(a,o,1).unproject(this.camera).clone().sub(s).normalize();return new Bo(s,c)}_intersectMeshAtRay(e,t,n){let r=new gm;r.ray.copy(t);let i=r.intersectObject(e,!1);if(!i.length)return null;if(n!=null){let e=i.find(e=>e.instanceId===n);return e?e.point:i[0].point}return i[0].point}_buildPickResult(e,t,n,r){let i=t.mesh.userData,a=null,o=e.batchId,s=e.instanceIndex,c=i.geoRef,l=[];if(s!=null){let e=this._instanceFeature(t.mesh,c,s);if(!e)return null;a=e.smid,o=e.batchId}else{c=i.geoByBatchId?.get(e.batchId)??i.geoRef;let t=Xg(c,e.batchId);a=t.smid,l=t.segments}if(this._isFeatureHidden(a,o))return null;let u=null,d=0;if(s!=null)u=this._instanceBox(t.mesh,s),d=t.mesh.geometry.index?Math.round(t.mesh.geometry.index.count/3):0;else if(a!=null&&this._smidMeshes.has(a)){let e=this._smidMeshes.get(a),t=1/0,n=1/0,r=1/0,i=-1/0,o=-1/0,s=-1/0,c=0;for(let l of e){let e=l.userData,u=e.geoRef?.pickInfo,f=u?.[a]??u?.[String(a)],p=f?Jg(f):-1,m=f?.segments??(p>=0?Xg(e.geoRef,p).segments:[]),h=Zg(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>o&&(o=h.maxY),h.maxZ>s&&(s=h.maxZ),c+=h.count,d+=h.triangles)}c>0&&(u={minX:t,minY:n,minZ:r,maxX:i,maxY:o,maxZ:s,count:c,triangles:d})}if(!u&&(u=Zg(t.mesh.geometry,l),!u&&t.mesh.geometry)){t.mesh.geometry.boundingBox||t.mesh.geometry.computeBoundingBox();let e=t.mesh.geometry.boundingBox;e&&(u={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 f=t.mesh.geometry,p=d>0?d:f.index?Math.round(f.index.count/3):0,m=Qg({smid:a,box:u,triangles:p,floorHeight:this.style.floorHeight}),h=null;if(u&&this.sceneAnchor){let e=new H((u.minX+u.maxX)/2,(u.minY+u.maxY)/2,(u.minZ+u.maxZ)/2);e.applyMatrix4(t.mesh.matrixWorld);let n=this.sceneAnchor.meterInMercator;h=this._lngLatFromWorld(e.x*n+this.sceneAnchor.x,-e.y*n+this.sceneAnchor.y)}let g=n??null;!g&&r&&(g=this._intersectMeshAtRay(t.mesh,r,s));let _=null,v=null,y=null;if(g&&this.sceneAnchor){let e=a==null?{}:this._featureStyleManager.getFeatureEffectiveOffset(a),t=e.translation,n=e.elevation,r=g.clone();t?r.add(new H(t[0],t[1],t[2])):n&&(r.z+=n),_=[r.x,r.y,r.z];let i=this.sceneAnchor.meterInMercator;v=this._lngLatFromWorld(r.x*i+this.sceneAnchor.x,-r.y*i+this.sceneAnchor.y),y=r.z+(this.sceneAnchor.altitude??0)}else h&&u&&this.sceneAnchor&&(v=h,y=(u.minZ+u.maxZ)/2+(this.sceneAnchor.altitude??0));return{datasetId:t.datasetId,datasetName:this.datasets.get(t.datasetId)?.name??t.datasetId,objectId:e.objectId,batchId:o,instanceIndex:s,skeletonName:t.skeletonName,centerLngLat:h,point:_,lngLat:v,altitude:y,...m,mesh:t.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,t){if(!this.camera||!this.sceneAnchor)return null;let n=this.pick(e,t);if(n?.point&&n?.lngLat&&n.altitude!=null)return{lngLat:n.lngLat,altitude:n.altitude,point:n.point};let r=this.getRayAt(e,t);if(!r)return null;let i=new Ac(new H(0,0,1),0),a=new H,o=r.intersectPlane(i,a);if(o){let e=this.sceneAnchor.meterInMercator;return{lngLat:this._lngLatFromWorld(o.x*e+this.sceneAnchor.x,-o.y*e+this.sceneAnchor.y),altitude:o.z+(this.sceneAnchor.altitude??0),point:[o.x,o.y,o.z]}}return null}drillPick(e,t,n=10){if(!this.sceneAnchor||!this.camera)return[];let r=this.getRayAt(e,t);if(!r)return[];let i=new gm;i.ray.copy(r);let a=[...this._pickables.values()].map(e=>e.mesh).filter(e=>{let t=e;for(;t;){if(!t.visible)return!1;t=t.parent}return!0}),o=i.intersectObjects(a,!1);if(!o.length)return[];let s=[],c=new Set,l=new Set;for(let e of o){if(s.length>=n)break;let t=e.object,r=t.userData;if(r.pickId==null)continue;let i=this._pickables.get(r.pickId);if(!i)continue;let a=null,o=-1,u=e.instanceId;if(u!=null){let e=this._instanceFeature(t,r.geoRef,u);if(!e)continue;a=e.smid,o=e.batchId}else if(e.faceIndex!=null){let n=t.geometry.attributes.aBatchId;if(n){let i=t.geometry.index?t.geometry.index.getX(e.faceIndex*3):e.faceIndex*3;o=Math.round(n.getX(i)),a=Xg(r.geoByBatchId?.get(o)??r.geoRef,o).smid}}if(a!=null){if(c.has(a))continue;c.add(a)}else{let e=`${r.pickId}:${o}:${u??-1}`;if(l.has(e))continue;l.add(e)}if(this._isFeatureHidden(a,o))continue;let d={objectId:r.pickId,batchId:o,instanceIndex:u},f=this._buildPickResult(d,i,e.point);f&&s.push(f)}return s}getFeatureBounds(e){if(!this.sceneAnchor)return null;let t=1/0,n=-1/0,r=1/0,i=-1/0,a=!1;for(let o of this._pickables.values()){let s=o.mesh,c=s.userData,l=c.geoRef,u=l?.pickInfo;if(!u)continue;let d=null;if(s.isInstancedMesh){let t=c.instanceLookup;t||(t=Yg(u),c.instanceLookup=t);for(let[n,r]of t)if(r.smid===e){d=this._instanceBox(s,n);break}}else{let t=u,n=t[e]??t[String(e)];if(n){let e=Xg(l,Jg(n));if(d=Zg(s.geometry,e.segments),!d&&s.geometry){s.geometry.boundingBox||s.geometry.computeBoundingBox();let e=s.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})}}}if(d){a=!0;let o=[new H(d.minX,d.minY,d.minZ),new H(d.maxX,d.minY,d.minZ),new H(d.minX,d.maxY,d.minZ),new H(d.maxX,d.maxY,d.minZ),new H(d.minX,d.minY,d.maxZ),new H(d.maxX,d.minY,d.maxZ),new H(d.minX,d.maxY,d.maxZ),new H(d.maxX,d.maxY,d.maxZ)],c=e==null?{}:this._featureStyleManager.getFeatureEffectiveOffset(e),l=c.translation,u=c.elevation;for(let e of o){l?e.add(new H(l[0],l[1],l[2])):u&&(e.z+=u),e.applyMatrix4(s.matrixWorld);let a=this.sceneAnchor.meterInMercator,[o,c]=this._lngLatFromWorld(e.x*a+this.sceneAnchor.x,-e.y*a+this.sceneAnchor.y);o<t&&(t=o),o>n&&(n=o),c<r&&(r=c),c>i&&(i=c)}}}return a?[[t,r],[n,i]]:null}_instanceFeature(e,t,n){let r=e.userData;return r.instanceLookup||(r.instanceLookup=Yg(t?.pickInfo)),r.instanceLookup.get(n)??null}_instanceBox(e,t){let n=e;if(!n.isInstancedMesh)return null;let r=e.geometry;r.boundingBox||r.computeBoundingBox();let i=r.boundingBox;if(!i)return null;let a=new U;n.getMatrixAt(t,a);let o=i.clone().applyMatrix4(a);return{minX:o.min.x,minY:o.min.y,minZ:o.min.z,maxX:o.max.x,maxY:o.max.y,maxZ:o.max.z,count:r.getAttribute(`position`)?.count??0,triangles:r.index?Math.round(r.index.count/3):0}}select(e,{silent:t=!1}={}){if(this._selection){for(let e of this._selectedMeshes){if(Bb(e)){this._applyPointCloudStyle(e,!1);continue}let t=zb(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=zb(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?Jg(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)Bb(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=>!Bb(e));t.length&&((this.style.outlineStyle??`edges`)===`edges`?this._addSelectionEdges(e,t):this._addSelectionHull(e,t))}this._requestRepaint()}_addSelectionEdges(e,t){this._syncSelectionStyle();for(let n of t){let t=n.userData,r=t.geoRef,i=[];if(n===e.mesh&&e.instanceIndex!=null)i=[{vertexOffset:0,vertexCount:n.geometry.getAttribute(`position`)?.count??0}];else if(e.smid!=null){let t=r?.pickInfo,n=t?.[e.smid]??t?.[String(e.smid)],a=n?Jg(n):-1;i=n?.segments??(a>=0?Xg(r,a).segments:[])}else n===e.mesh&&(i=Xg(t.geoByBatchId?.get(e.batchId)??r,e.batchId).segments);let a=kb(n.geometry,i);if(a&&a.length>0){let t=new dc(Eb(a),this.selectionEdgeMaterial);t.renderOrder=4,t.frustumCulled=!1,t.raycast=()=>{},t.userData.isSelectionEdge=!0,n===e.mesh&&e.instanceIndex!=null&&this._applyInstanceTransform(t,e),n.add(t),this._selectionEdgeMeshes.push(t)}}this._selectionEdgeMeshes.length===0?this._addSelectionHull(e,t):this._selectionEdges=this._selectionEdgeMeshes[0]??null}_applyInstanceTransform(e,t){let n=t.mesh;if(t.instanceIndex==null||!n.isInstancedMesh)return;let r=new U;n.getMatrixAt(t.instanceIndex,r),r.decompose(e.position,e.quaternion,e.scale)}_addSelectionHull(e,t){let n=e.instanceIndex!=null;this.outlineMaterial.uniforms.uSelBatch.value=n?-1:e.batchId,this.outlineMaterial.uniforms.uSelWhole.value=n||e.batchId<0?1:0,this.outlineMaterial.uniforms.uElevation.value=n?this._selectionElevation(e):this.style.selectElevation??0;for(let n of t){let t=zb(n);t?.userData?.uBatchTex&&(this.outlineMaterial.uniforms.uBatchTex.value=t.userData.uBatchTex.value,this.outlineMaterial.uniforms.uBatchTexWidth.value=t.userData.uBatchTexWidth.value,this.outlineMaterial.uniforms.uBatchTexActive.value=t.userData.uBatchTexActive.value);let r=new dc(n.geometry,this.outlineMaterial);r.renderOrder=3,r.frustumCulled=!1,r.raycast=()=>{},n===e.mesh&&e.instanceIndex!=null&&this._applyInstanceTransform(r,e),n.add(r),this._outlineMeshes.push(r)}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?zb(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;let t=this.renderer.getContext();if(t&&typeof t.isContextLost==`function`&&t.isContextLost())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 U().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===hy.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===hy.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=ib(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()}};X(Vb,`_EDGE_SKIP_KEYWORDS`,[`terrain`,`ground`,`vegetation`,`green`,`road`,`dem`,`绿地`,`道路`,`地面`,`地形`,`植被`,`铺装`]),rh();var Hb=1e-4;function Ub(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])>Hb*r)return!1}return!0}function Wb(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 Gb(e,t){return t>0&&Math.abs(e.elements[5]*Math.tan(t/2)-1)<.001}function Kb(e){if(!e||typeof e!=`object`)return null;let t=e;return t.defaultProjectionData?.projectionMatrix??t.projectionMatrix??null}function qb(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 Jb(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 Yb(e,t){let n=e.projectionMatrix;if(!n||n.length<16)return null;let r=new U().fromArray(Array.from(n)),i=new U().fromArray(Array.from(e.mvp));if(r.determinant()===0||!Gb(r,t.fov))return null;let a=r.clone().invert().multiply(i);if(!Ub(r.clone().multiply(a),Array.from(e.mvp))||!Wb(a)||!Gb(r,t.fov))return null;let{distance:o,fov:s,aspect:c}=t;if(!(o>0)||!(s>0)||!(c>0))return null;let l=o*Math.tan(s/2),u=l*c,d=e.nearZ!=null&&e.nearZ>0?e.nearZ:1,f=e.farZ!=null&&e.farZ>d?e.farZ:o*4+1e3;f>d||(f=d+1e3);let p=new zc(-u,u,l,-l,d,f);return p.updateProjectionMatrix(),{matrix:p.projectionMatrix.clone().multiply(a),view:a}}var Xb=.6435011087932844;function Zb(e){let t=e,n=t?.transform?.worldCoordinateHelper??t?.transform?.projection?.worldCoordinateHelper??t?.painter?.transform?.worldCoordinateHelper??(typeof t?.getProjection==`function`?t.getProjection()?.worldCoordinateHelper:null)??null;return n&&typeof n.worldFromLngLat==`function`&&typeof n.lngLatFromWorld==`function`?n:null}function Qb(e){let t=Zb(e);return t?{worldFromLngLat(e,n,r=0){let i=t.worldFromLngLat(e,n,r),a=0;if(typeof t.metersPerWorldUnit==`function`){let e=t.metersPerWorldUnit(i.x,i.y);Number.isFinite(e)&&e>0&&(a=1/e)}if(a===0){let o=t.worldFromLngLat(e,n,r+1),s=Math.abs((o.z??0)-(i.z??0));Math.sin(n*Math.PI/180),a=s>0?s:1/(2*Math.PI*6378137)/Math.cos(n*Math.PI/180)}return{x:i.x,y:i.y,z:i.z??r*a,meterInMercator:a,altitude:r}},lngLatFromWorld(e,n){let r=t.lngLatFromWorld(e,n);return Array.isArray(r)?[r[0],r[1]]:r&&typeof r.lng==`number`&&typeof r.lat==`number`?[r.lng,r.lat]:[0,0]}}:null}rh();var $b=class{get map(){return this._map}set map(e){this._map=e,this.viewer.geo=e?Qb(e):null}_mapGl(){let e=this.map?.getCanvas?.();return e?e.getContext(`webgl2`)??e.getContext(`webgl`):null}constructor(e={}){X(this,`id`,void 0),X(this,`type`,`custom`),X(this,`renderingMode`,`3d`),X(this,`options`,void 0),X(this,`pickable`,void 0),X(this,`onStats`,void 0),X(this,`onReady`,void 0),X(this,`onPick`,void 0),X(this,`onError`,void 0),X(this,`_map`,null),X(this,`viewer`,void 0),X(this,`_orthoWarned`,!1),X(this,`_projection`,`perspective`),X(this,`_onProjectionChange`,()=>{this.map&&(this.viewer.geo=Qb(this.map)),this.viewer.recomputeAnchors()}),X(this,`_contextLost`,!1),X(this,`_listenersAttached`,!1),X(this,`_onContextLost`,()=>{this._contextLost=!0}),X(this,`_onContextRestored`,()=>{this._contextLost=!1;let e=this.map;if(e){try{let t=e.getLayer,n=e.addLayer;if(!(typeof t==`function`&&t.call(e,this.id)))typeof n==`function`&&n.call(e,this);else{let e=this._mapGl();e&&this.viewer.restoreContext(e)}}catch(e){console.warn(`[s3m] WebGL 上下文恢复后重加图层失败,请手动 map.addLayer(layer)`,e)}e.triggerRepaint()}}),X(this,`_onClick`,e=>{if(!this.pickable)return;let t=this.pickFromEvent(e);t?(this.select(t),this.onPick(t)):this.select(null)}),this.id=e.id??`s3m`,this.options=e,this.pickable=e.pickable!==!1,this._projection=e.projection===`orthographic`?`orthographic`:`perspective`,this.onStats=e.onStats??(()=>{}),this.onReady=e.onReady??(()=>{}),this.onPick=e.onPick??(()=>{}),this.onError=e.onError??(e=>console.warn(`[s3m]`,e)),this.viewer=new Vb({configUrl:e.configUrl,datasets:e.datasets,style:e.style,ground:e.ground,pickable:e.pickable,maxTiles:e.maxTiles,maxConcurrent:e.maxConcurrent,lodRangeScale:e.lodRangeScale,buildTile:e.buildTile,light:e.light,totalMaxTiles:e.totalMaxTiles,attributes:e.attributes,onRequestRepaint:()=>this.map?.triggerRepaint(),getBearing:()=>this.map?.getBearing?.()??0,onStats:e=>this.onStats(e),onReady:e=>this.onReady(e),onPick:e=>this.onPick(e),onError:e=>this.onError(e)})}onAdd(e,t){this.map=e,this.viewer.renderer?this.viewer.restoreContext(t):this.viewer.mount(e.getCanvas(),t),this._listenersAttached||(e.on(`click`,this._onClick),typeof e.on==`function`&&(e.on(`projectiontransition`,this._onProjectionChange),e.on(`webglcontextlost`,this._onContextLost),e.on(`webglcontextrestored`,this._onContextRestored)),this._listenersAttached=!0)}onRemove(){this.map?.off(`click`,this._onClick),typeof this.map?.off==`function`&&(this.map.off(`projectiontransition`,this._onProjectionChange),this.map.off(`webglcontextlost`,this._onContextLost),this.map.off(`webglcontextrestored`,this._onContextRestored)),this._listenersAttached=!1,this._contextLost=!1,this.viewer.unmount(),this.viewer.geo=null,this.map=null}_extractMatrix(e){if(Array.isArray(e)||e instanceof Float64Array||e instanceof Float32Array)return e;let t=e;return t?.defaultProjectionData?.mainMatrix??t?.modelViewProjectionMatrix??null}_applyOrtho(e,t){let{nearZ:n,farZ:r}=qb(e),i=Kb(e);if(!i)return this._warnOrtho(`render() 输入里没有独立的投影矩阵(需要 MapLibre ≥ 5)`),null;let a=Yb({projectionMatrix:i,mvp:t.elements,nearZ:n,farZ:r},{distance:this.map?.transform?.cameraToCenterDistance??0,fov:this._frameFov(e),aspect:this._canvasAspect()});return a?a.matrix:(this._warnOrtho(`拿到的投影矩阵与 MVP 不同源(反推结果不是仿射变换)`),null)}_warnOrtho(e){this._orthoWarned||(this._orthoWarned=!0,console.warn(`[s3m] 正交模式不可用:${e},本帧保持透视`))}_frameFov(e){return Jb(e,this.map?.transform?.fovInRadians)??.6435011087932844}_canvasAspect(){let e=this.map?.getCanvas?.();return!e||!e.height?1:e.width/e.height}setProjection(e){let t=e===`orthographic`?`orthographic`:`perspective`;this._projection!==t&&(this._projection=t,this._orthoWarned=!1,this.map?.triggerRepaint())}get projection(){return this._projection}render(e,t){let n=this.map,r=this.viewer.sceneAnchor;if(!n||!r||this._contextLost)return;let i=this._extractMatrix(t);if(!i)return;let a=new U().fromArray(i);this._projection===`orthographic`&&(a=this._applyOrtho(t,a)??a);let o=n.getCanvas(),s=r.meterInMercator,c=[0,0,0];try{let e=n.getFreeCameraOptions?.()?.position;e&&(c=[(e.x-r.x)/s,-(e.y-r.y)/s,(e.z-r.z)/s])}catch{}this.viewer.renderFrame({mvp:a.elements,cameraEnu:c,fovRad:this._frameFov(t),canvasHeight:o.height})&&n.triggerRepaint()}pickFromEvent(e){let t=this.map?.getCanvas();if(!t)return null;let n=t.getBoundingClientRect(),r=e.originalEvent??e;return this.viewer.pick(r.clientX-n.left,r.clientY-n.top)}pick(e,t){return this.viewer.pick(e,t)}pickPosition(e,t){return this.viewer.pickPosition(e,t)}drillPick(e,t,n=10){return this.viewer.drillPick(e,t,n)}getRayAt(e,t){return this.viewer.getRayAt(e,t)}select(e,t={}){this.viewer.select(e,t)}getFeatureBounds(e){return this.viewer.getFeatureBounds(e)}flyToFeature(e,t){let n=this.viewer.getFeatureBounds(e);if(!n||!this.map)return!1;let r=this.map;return typeof r.fitBounds==`function`&&(r.fitBounds(n,{padding:50,maxZoom:19,duration:1200,...t}),!0)}addDataset(e){return this.viewer.addDataset(e)}removeDataset(e){this.viewer.removeDataset(e)}clearDatasets(){this.viewer.clearDatasets()}setDatasetVisible(e,t){this.viewer.setDatasetVisible(e,t)}getDatasetHeight(e){return this.viewer.getDatasetHeight(e)}setDatasetHeight(e,t){this.viewer.setDatasetHeight(e,t)}setDatasetAlign(e,t){this.viewer.setDatasetAlign(e,t)}_computeAlignOffset(e,t){return this.viewer.computeAlignOffset(e,t)}setLight(e){this.viewer.setLight(e)}getLight(){return this.viewer.getLight()}setOpacity(e){this.viewer.setOpacity(e)}setStyle(e={}){this.viewer.setStyle(e)}getStyle(){return this.viewer.getStyle()}setEdges(e){this.viewer.setEdges(e)}loadCreases(e){return this.viewer.loadCreases(e)}clearCreases(){this.viewer.clearCreases()}setFeatureStyle(e,t){this.viewer.setFeatureStyle(e,t)}setFeaturesStyle(e,t){this.viewer.setFeaturesStyle(e,t)}getFeatureStyle(e){return this.viewer.getFeatureStyle(e)}getFeatureStyles(){return this.viewer.getFeatureStyles()}removeFeatureStyle(e){this.viewer.removeFeatureStyle(e)}clearFeatureStyles(){this.viewer.clearFeatureStyles()}setAttributeSource(e){this.viewer.setAttributeSource(e)}getLoadedSmids(){return this.viewer.getLoadedSmids()}auditBatches(){return this.viewer.auditBatches()}getThematicField(){return this.viewer.getThematicField()}setThematicColors(e,t=`custom`){this.viewer.setThematicColors(e,t)}clearThematic(){this.viewer.clearThematic()}getFilterField(){return this.viewer.getFilterField()}filterByField(e){return this.viewer.filterByField(e)}clearFieldFilter(){this.viewer.clearFieldFilter()}getElevationField(){return this.viewer.getElevationField()}elevateByField(e){return this.viewer.elevateByField(e)}setThematicElevation(e,t=`custom`){this.viewer.setThematicElevation(e,t)}clearThematicElevation(){this.viewer.clearThematicElevation()}colorByField(e){return this.viewer.colorByField(e)}setFilter(e){this.viewer.setFilter(e)}getFilter(){return this.viewer.getFilter()}clearFilter(){this.viewer.clearFilter()}setGroundMode(e){this.viewer.setGroundMode(e)}setGroundOpacity(e){this.viewer.setGroundOpacity(e)}setExcavationBounds(e){this.viewer.setExcavationBounds(e)}setGroundOcclude(e){this.viewer.setGroundOcclude(e)}get groundManager(){return this.viewer.groundManager}getAllMeshes(){return this.viewer.getAllMeshes()}flushOverrides(){this.viewer.flushOverrides()}_applyOverridesToMesh(e){this.viewer._applyOverridesToMesh(e)}get lodRangeScale(){return this.viewer.lodRangeScale}setLodRangeScale(e,t){this.viewer.setLodRangeScale(e,t)}get renderer(){return this.viewer.renderer}get scene(){return this.viewer.scene}get camera(){return this.viewer.camera}get picker(){return this.viewer.picker}get uniforms(){return this.viewer.uniforms}get style(){return this.viewer.style}get outlineMaterial(){return this.viewer.outlineMaterial}get lineShared(){return this.viewer.lineShared}get edgeMaterial(){return this.viewer.edgeMaterial}get selectionEdgeMaterial(){return this.viewer.selectionEdgeMaterial}get datasets(){return this.viewer.datasets}get sceneAnchor(){return this.viewer.sceneAnchor}set sceneAnchor(e){this.viewer.sceneAnchor=e}get attributeQuery(){return this.viewer.attributeQuery}get fps(){return this.viewer.fps}get stats(){return this.viewer.stats}getBounds(){return this.viewer.getBounds()}dispose(){this.onRemove()}},ex=i({AttributeQuery:()=>o_,BinaryReader:()=>sh,DEFAULT_FLOOR_HEIGHT:()=>e_,DEFAULT_FOV:()=>Xb,DEFAULT_STYLE:()=>yy,DatasetManager:()=>jb,EARTH_RADIUS:()=>s_,FeatureStyleManager:()=>Ib,GroundManager:()=>Lb,Picker:()=>xb,PixelFormat:()=>ly,S3MFormatError:()=>Kg,S3MLayer:()=>$b,S3MTileset:()=>sb,S3MViewer:()=>Vb,S3M_VERSION:()=>mg,SELECT_MODE:()=>_y,SELECT_MODE_LABELS:()=>vy,STYLE:()=>hy,STYLE_LABELS:()=>gy,TextureCompress:()=>J_,VertexTag:()=>hg,VertexTagV3:()=>gg,buildAttributes:()=>Qg,buildFeatureEdgeSegments:()=>kb,buildOrthoMVP:()=>Yb,buildThickLineGeometry:()=>Eb,buildTileObjects:()=>Jy,createLineSharedUniforms:()=>Sb,createMapLibreGeoAdapter:()=>Qb,createOutlineMaterial:()=>my,createSharedUniforms:()=>fy,createStyledMaterial:()=>py,createTexture:()=>cy,createThickLineMaterial:()=>Tb,default:()=>$b,dxtPixelFormatOf:()=>q_,extractFovRadians:()=>Jb,extractNearFar:()=>qb,extractProjectionMatrix:()=>Kb,extractWorldCoordinateHelper:()=>Zb,isS3M1Buffer:()=>tg,lngLatFromMercator:()=>l_,lngLatFromWorld:()=>d_,measureSegments:()=>Zg,mercatorFromLngLat:()=>c_,parseS3M1:()=>pg,parseS3MB:()=>qg,resolveFeature:()=>Xg,resolveTextureKind:()=>K_,setMaxAnisotropy:()=>ty,worldFromLngLat:()=>u_});rh(),t_(),Z_(),dy(),jy(),Zy();var tx=globalThis;return tx.THREE||(tx.THREE=a),tx.S3MMapLibre=ex,e.AttributeQuery=o_,e.BinaryReader=sh,e.DEFAULT_FLOOR_HEIGHT=e_,e.DEFAULT_FOV=Xb,e.DEFAULT_STYLE=yy,e.DatasetManager=jb,e.EARTH_RADIUS=s_,e.FeatureStyleManager=Ib,e.GroundManager=Lb,e.Picker=xb,e.PixelFormat=ly,e.S3MFormatError=Kg,e.S3MLayer=$b,e.default=$b,e.S3MTileset=sb,e.S3MViewer=Vb,e.S3M_VERSION=mg,e.SELECT_MODE=_y,e.SELECT_MODE_LABELS=vy,e.STYLE=hy,e.STYLE_LABELS=gy,e.TextureCompress=J_,e.VertexTag=hg,e.VertexTagV3=gg,e.buildAttributes=Qg,e.buildFeatureEdgeSegments=kb,e.buildOrthoMVP=Yb,e.buildThickLineGeometry=Eb,e.buildTileObjects=Jy,e.createLineSharedUniforms=Sb,e.createMapLibreGeoAdapter=Qb,e.createOutlineMaterial=my,e.createSharedUniforms=fy,e.createStyledMaterial=py,e.createTexture=cy,e.createThickLineMaterial=Tb,e.dxtPixelFormatOf=q_,e.extractFovRadians=Jb,e.extractNearFar=qb,e.extractProjectionMatrix=Kb,e.extractWorldCoordinateHelper=Zb,e.isS3M1Buffer=tg,e.lngLatFromMercator=l_,e.lngLatFromWorld=d_,e.measureSegments=Zg,e.mercatorFromLngLat=c_,e.parseS3M1=pg,e.parseS3MB=qg,e.resolveFeature=Xg,e.resolveTextureKind=K_,e.setMaxAnisotropy=ty,e.worldFromLngLat=u_,e})({});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "s3m-maplibre",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "description": "SuperMap S3M 三维模型格式的 MapLibre / Mapbox 原生渲染图层:浏览器内直接解析 .s3mb 瓦片,无需转 3D Tiles,支持多数据集叠加、白膜/按高度/按单体/动态扫描着色、单体级 GPU 拾取与属性查询。基于 s3m-three 渲染内核。",
5
5
  "type": "module",
6
6
  "repository": {
@@ -60,7 +60,7 @@
60
60
  "author": "",
61
61
  "license": "Apache-2.0",
62
62
  "dependencies": {
63
- "s3m-three": "^0.3.4"
63
+ "s3m-three": "^0.3.5"
64
64
  },
65
65
  "peerDependencies": {
66
66
  "three": ">=0.155.0"