import{_ as ae}from"./geotiff-BaoeLn6q.js";import{M as le}from"./bootstrap-D1-uvFxm.js";import{ax as ie}from"./openlayers-J9qS6Th1.js";import{i as G,f as I,a as ue,b as ce,c as de,d as pe,e as fe,g as me}from"./turf-B-0GbNlN.js";import{s as O}from"./index-Cyeghdft.js";import"./pako-Xa-UToif.js";import"./ol-ext-C5frl4dY.js";import"./shpjs-Doisr2ug.js";const X=4e5,ye=new ie;function L(e,n="EPSG:3857"){const o=[];for(const r of e||[]){if(!(r.getGeometry&&r.getGeometry()))continue;const s=ye.writeFeatureObject(r,{dataProjection:"EPSG:4326",featureProjection:n});s&&s.geometry&&o.push(s)}return o}function A(e){const n=e&&e.geometry;if(!n||!n.coordinates)return null;let o=1/0,r=1/0,a=-1/0,s=-1/0;const i=l=>{if(typeof l[0]=="number"){l[0]a&&(a=l[0]),l[1]s&&(s=l[1]);return}for(const u of l)i(u)};return i(n.coordinates),Number.isFinite(o)?[o,r,a,s]:null}function H(e,n){return!e||!n?!1:!(e[2]=e[0]&&n<=e[2]&&o>=e[1]&&o<=e[3]:!1}function z(e){return(e||[]).filter(n=>{const o=n?.geometry?.type;return o==="Polygon"||o==="MultiPolygon"})}function ge(e,n,o="b_"){const r={...e||{}};for(const[a,s]of Object.entries(n||{}))r[Object.prototype.hasOwnProperty.call(r,a)?`${o}${a}`:a]=s;return r}function S(e){return{type:"FeatureCollection",features:e}}function Y(e,n,o={}){const{keepBAttributes:r=!0}=o,a=z(L(e)),s=z(L(n)),i=s.map(A);let l=0;const u=[];for(const d of a){const m=A(d);for(let p=0;pX)throw q(l);let c=null;try{c=ce(I([d,s[p]]))}catch{c=null}!c||!c.geometry||(c.properties=r?ge(d.properties,s[p].properties):{...d.properties||{}},u.push(c))}}return S(u)}function be(e,n,o={}){return Y(e,n,{...o,keepBAttributes:!1})}function we(e,n){const o=z(L(e)),r=z(L(n)),a=r.map(A);let s=0;const i=[];for(const l of o){const u=A(l);let d=l;for(let m=0;mX)throw q(s);try{const p=ue(I([d,r[m]]));d=p&&p.geometry?p:null}catch{}}d&&d.geometry&&(d.properties={...l.properties||{}},i.push(d))}return S(i)}function ve(e,n=[]){const o=z([...L(e),...L(n)]);if(o.length===0)return S([]);if(o.length===1)return S([o[0]]);let r=null;try{r=G(I(o))}catch{r=o[0];for(let a=1;a{const E=y?.geometry?.type;return E==="Polygon"||E==="MultiPolygon"}),l=L(n)||[];if(i.length===0)throw new Error("The zone layer contains no polygons.");const u=a==="centroid"?l.map(y=>{try{return de(y)}catch{return null}}):null,d=a==="centroid"?null:l.map(A),m=i.map(A);let p=0;const c=[];for(let y=0;yZ)throw V(p);g=pe(x,E)}else{if(!H(D,d[f]))continue;if(++p>Z)throw V(p);g=fe(l[f],E)}}catch{g=!1}g&&M.push(l[f])}const v=r?M.map(f=>Be(f.properties?f.properties[r]:null)).filter(f=>f!==null):[],B={};for(const f of o)switch(f){case"count":B[`${s}count`]=M.length;break;case"sum":B[`${s}sum`]=v.length?_(v.reduce((g,x)=>g+x,0)):0;break;case"mean":B[`${s}mean`]=v.length?_(v.reduce((g,x)=>g+x,0)/v.length):null;break;case"min":B[`${s}min`]=v.length?_(Math.min(...v)):null;break;case"max":B[`${s}max`]=v.length?_(Math.max(...v)):null;break;case"area":{let g=0;for(const x of M)try{g+=me(x)}catch{}B[`${s}area_m2`]=Math.round(g);break}}E.properties={...E.properties||{},...B},c.push({...ke(E),...B})}return{geojson:{type:"FeatureCollection",features:i},rows:c}}function V(e){return new Error(`More than ${e.toLocaleString()} features fall within the zones' bounding boxes, which is too much to summarise in the browser. Narrow the inputs using “Apply to” (current map view or selected features).`)}function _(e){return Math.round(e*1e3)/1e3}function ke(e){const n=e.properties||{};for(const o of["zone_name","name","ZONE_NAME","NAME","upn","UPN","id","ID"])if(n[o]!==void 0&&n[o]!==null&&String(n[o]).trim()!=="")return{zone:String(n[o])};return{zone:"(unnamed)"}}const Se=9001,C="Analysis",t={};let F=null,b=null,$=[],w=null,k=null;function $e(){t.root||(t.root=document.getElementById("analysisModal"),t.mode=Array.from(document.querySelectorAll('input[name="analysis-mode"]')),t.overlayBox=document.getElementById("analysis-overlay-box"),t.zonalBox=document.getElementById("analysis-zonal-box"),t.op=document.getElementById("analysis-op"),t.opHint=document.getElementById("analysis-op-hint"),t.layerA=document.getElementById("analysis-layer-a"),t.layerB=document.getElementById("analysis-layer-b"),t.layerBWrap=document.getElementById("analysis-layer-b-wrap"),t.zoneLayer=document.getElementById("analysis-zone-layer"),t.inputLayer=document.getElementById("analysis-input-layer"),t.membership=document.getElementById("analysis-membership"),t.memberHint=document.getElementById("analysis-membership-hint"),t.field=document.getElementById("analysis-field"),t.statsBox=document.getElementById("analysis-stats-box"),t.outName=document.getElementById("analysis-output-name"),t.result=document.getElementById("analysis-result"),t.btnRun=document.getElementById("analysis-run"),t.btnExport=document.getElementById("analysis-export-table"),t.scope=document.getElementById("analysis-scope"),t.scopeHint=document.getElementById("analysis-scope-hint"),t.root.dataset.wired||(t.root.dataset.wired="1",t.mode.forEach(e=>e.addEventListener("change",K)),t.op.addEventListener("change",Q),t.membership.addEventListener("change",ee),t.inputLayer.addEventListener("change",J),t.scope.addEventListener("change",ne),t.btnRun.addEventListener("click",Me),t.btnExport.addEventListener("click",Ne)))}function U(e=null){return $.map((n,o)=>``).join("")}function Ae(){t.op.innerHTML=P.map(e=>``).join(""),t.membership.innerHTML=j.map(e=>``).join(""),t.statsBox.innerHTML=T.map(e=>`
`).join("")}function J(){const e=$[Number(t.inputLayer.value)],n=e?e.layer.getSource().getFeatures():[],o=Ee(n);t.field.innerHTML=''+o.map(r=>``).join(""),t.field.disabled=o.length===0}function R(){return(t.mode.find(e=>e.checked)||{}).value||"overlay"}function K(){k=null,oe();const e=R()==="overlay";t.overlayBox.classList.toggle("d-none",!e),t.zonalBox.classList.toggle("d-none",e),te()}function Q(){const e=P.find(o=>o.key===t.op.value);t.opHint.textContent=e?e.hint:"";const n=e?e.needsB:!0;t.layerBWrap.querySelector("label").textContent=n?"Layer B":"Layer B (optional)",te()}function ee(){const e=j.find(n=>n.key===t.membership.value);t.memberHint.textContent=e?e.hint:""}function te(){if(t.outName.dataset.touched!=="1")if(R()==="overlay"){const e=t.op.value||"overlay";t.outName.value=`${e}_result`}else t.outName.value="zonal_stats"}function N(e){const n=$[Number(e.value)];if(!n)return[];const o=n.layer.getSource(),r=t.scope?t.scope.value:"all";if(r==="view"){const a=b.getMap(),s=a.getView().calculateExtent(a.getSize());return o.getFeaturesInExtent(s)}if(r==="selection"){const a=new Set(b.getSelectedFeatures());return o.getFeatures().filter(s=>a.has(s))}return r==="drawn"&&w?o.getFeatures().filter(a=>w.features.has(a)):o.getFeatures()}function ne(){const e=t.scope.value;if(e==="drawn"&&w)t.scopeHint.textContent=`${w.features.size.toLocaleString()} feature(s) caught by the ${w.label}.`;else if(e==="selection"){const n=b?b.getSelectedFeatures().length:0;t.scopeHint.textContent=n===0?"Nothing selected yet — use the Digitise tool: shift-click features, or hold Ctrl/Cmd and drag a box.":`${n.toLocaleString()} feature(s) currently selected.`}else e==="view"?t.scopeHint.textContent="Only features inside the current map view are analysed — zoom to the area of interest first.":t.scopeHint.textContent="Every feature in the chosen layer. Narrow this if a large layer is slow."}function ze(){let e=b.getLayerGroupByTitle(C);return e||(b.addLayerGroup(Se,C,"Results of client-side spatial analysis"),e=b.getLayerGroupByTitle(C)),e}function Me(){t.result.innerHTML="",t.btnRun.disabled=!0,setTimeout(()=>{try{const e=R(),n=(t.outName.value||"").trim()||(e==="overlay"?"overlay_result":"zonal_stats");let o,r;if(e==="overlay"){k=null;const s=t.op.value,i=N(t.layerA),l=N(t.layerB),u=(P.find(d=>d.key===s)||{}).needsB;if(i.length===0)throw new Error("Layer A has no features.");if(u&&l.length===0)throw new Error("This operation needs a second layer with features.");o=xe(s,i,l),r=`${o.features.length.toLocaleString()} feature(s) produced.`}else{const s=N(t.zoneLayer),i=N(t.inputLayer),l=Array.from(t.statsBox.querySelectorAll("input:checked")).map(c=>c.value),u=t.field.value||null;if(l.length===0)throw new Error("Select at least one statistic.");if(l.some(c=>(T.find(y=>y.key===c)||{}).needsField)&&!u)throw new Error("Sum / mean / min / max need a numeric field.");const m=Le({zoneFeatures:s,inputFeatures:i,stats:l,field:u,membership:t.membership.value});o=m.geojson,r=Ie(m.rows);const p=(j.find(c=>c.key===t.membership.value)||{}).label;k={rows:m.rows,params:{Analysis:"Zonal statistics","Zone layer":W(t.zoneLayer),"Features summarised":W(t.inputLayer),"Applied to":_e(),"Zones analysed":s.length,"Features analysed":i.length,"Counted when":p||t.membership.value,Statistics:l.map(c=>(T.find(y=>y.key===c)||{}).label||c).join(", "),"Numeric field":u||"(none)","Result layer":n}}}if(!o.features.length){t.result.innerHTML='
No result features — the layers may not overlap.
';return}const a=ze();b.addGeoJSONLayer(o,n,{strokeColor:"#d97706",strokeWidth:2,fillColor:"rgba(217,119,6,0.18)"},a),oe(),t.result.innerHTML=`
Added layer “${h(n)}”.
`+(typeof r=="string"&&r.startsWith("<")?r:`
${h(r)}
`),O(`Analysis complete — “${n}” added to the Analysis group.`,"success",4e3)}catch(e){console.error("[Analysis] run failed:",e),t.result.innerHTML=`
${h(e.message||String(e))}
`}finally{t.btnRun.disabled=!1}},20)}function W(e){const n=e.options[e.selectedIndex];return n?n.textContent:"(none)"}function _e(){const e=t.scope.options[t.scope.selectedIndex];return e?e.textContent:"Whole layer"}async function Ne(){if(k){t.btnExport.disabled=!0;try{const{exportXlsx:e}=await ae(async()=>{const{exportXlsx:l}=await import("./xlsx-d1LrY7GM.js");return{exportXlsx:l}},[]),{rows:n,params:o}=k,r=Object.keys(n[0]||{}).filter(l=>l!=="zone"),a=[{cells:["Zone",...r],bold:!0},...n.map(l=>["zone"in l?l.zone:"",...r.map(u=>l[u]===null||l[u]===void 0?"":l[u])])],s=[{cells:["LUPMIS2 — Zonal statistics"],bold:!0},[],{cells:["Parameter","Value"],bold:!0},...Object.entries(o).map(([l,u])=>[l,u]),["Exported",new Date().toLocaleString()]],i=(o["Result layer"]||"zonal_stats").toString().trim().replace(/[^A-Za-z0-9_\-]+/g,"_")||"zonal_stats";e([{name:"Parameters",rows:s},{name:"Results",rows:a}],`${i}.xlsx`),O("Table exported to Excel.","success",3e3)}catch(e){console.error("[Analysis] table export failed:",e),O(`Could not export the table: ${e.message}`,"error",6e3)}finally{t.btnExport.disabled=!1}}}function oe(){t.btnExport&&t.btnExport.classList.toggle("d-none",!k)}function Ie(e){if(!e||!e.length)return"";const n=Object.keys(e[0]).filter(a=>a!=="zone"),o=["Zone",...n.map(a=>a.replace(/^zs_/,""))].map(a=>`${h(a)}`).join(""),r=e.map(a=>`${h(String(a.zone))}`+n.map(s=>`${a[s]===null||a[s]===void 0?"—":h(String(a[s]))}`).join("")+"").join("");return`
${o}${r}
`}function Ge(e,n={}){if(b=e,$e(),w=n.scopeFeatures&&n.scopeFeatures.length?{features:new Set(n.scopeFeatures),label:n.scopeLabel||"drawn area"}:null,Oe(),$=b.listVectorLayers({nonEmptyOnly:!0}),$.length===0){O("No vector layers with features are loaded — nothing to analyse yet.","warning",5e3);return}Ae();const o=U(0),r=U($.length>1?1:0);t.layerA.innerHTML=o,t.layerB.innerHTML=r,t.zoneLayer.innerHTML=o,t.inputLayer.innerHTML=r,t.outName.dataset.touched="",t.outName.addEventListener("input",()=>{t.outName.dataset.touched="1"},{once:!0}),t.result.innerHTML="",k=null,t.scope.value=w?"drawn":"all",J(),Q(),ee(),ne(),K(),F=F||new le(t.root),F.show()}function Oe(){const e=t.scope.querySelector('option[value="drawn"]');if(!w){e&&e.remove();return}const n=`From ${w.label} (${w.features.size.toLocaleString()} features)`;if(e)e.textContent=n;else{const o=document.createElement("option");o.value="drawn",o.textContent=n,t.scope.insertBefore(o,t.scope.firstChild)}}function h(e){return String(e).replace(/[&<>"']/g,n=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[n])}export{Ge as openAnalysisModal}; //# sourceMappingURL=analysis-modal-05Uf_OF7.js.map