@vertigis/arcgis-extensions 53.0.0 → 53.2.0

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.
package/data/convert.d.ts CHANGED
@@ -10,6 +10,10 @@ import type { GeometryType } from "../support/esri.js";
10
10
  import { DateFormat, NumberFormat, TimeFormat } from "../utilities/format/formats.js";
11
11
  import { FeatureSet } from "./FeatureSet.js";
12
12
  import type { IDxfJsonComponentContext } from "./support/_dxfInterfaces.js";
13
+ /**
14
+ * A union of simple fill, line, and marker symbols.
15
+ */
16
+ export type SimpleSymbol = SimpleFillSymbol | SimpleLineSymbol | SimpleMarkerSymbol;
13
17
  export declare const FIELD_NAME_REGEX: RegExp;
14
18
  /**
15
19
  * Data for a cell in a table.
@@ -392,7 +396,7 @@ export declare function parseKMLCoordinates(coordinates: string): {
392
396
  * default symbol in case there is no style element.
393
397
  * @param index The index used to alternate symbol colors between features.
394
398
  */
395
- export declare function parseKMLSymbol(style: Element | undefined, geometryType: GeometryType, index: number): PictureMarkerSymbol | SimpleFillSymbol | SimpleLineSymbol | SimpleMarkerSymbol;
399
+ export declare function parseKMLSymbol(style: Element | undefined, geometryType: GeometryType, index: number): PictureMarkerSymbol | SimpleSymbol;
396
400
  /**
397
401
  * Converts a {@link data/FeatureSet!FeatureSet } to a zipped shapefile blob.
398
402
  *
@@ -439,5 +443,5 @@ export declare function shapefileToFeatureSet(shapefileData: Blob, options?: Fro
439
443
  * @param colorIndex The index used to alternate symbol colors.
440
444
  * @param geometryType The geometry type used to return the appropriate symbol.
441
445
  */
442
- export declare function getDefaultSymbol(colorIndex: number, geometryType: GeometryType): SimpleMarkerSymbol | SimpleLineSymbol | SimpleFillSymbol | MeshSymbol3D | undefined;
446
+ export declare function getDefaultSymbol(colorIndex: number, geometryType: GeometryType): SimpleSymbol | MeshSymbol3D | undefined;
443
447
  export {};
package/data/convert.js CHANGED
@@ -1 +1 @@
1
- import e from"@arcgis/core/Color.js";import t from"@arcgis/core/Graphic.js";import r from"@arcgis/core/geometry/Point";import o from"@arcgis/core/geometry/Polygon.js";import n from"@arcgis/core/geometry/Polyline.js";import a from"@arcgis/core/geometry/SpatialReference";import i from"@arcgis/core/layers/FeatureLayer.js";import s from"@arcgis/core/layers/GroupLayer.js";import c from"@arcgis/core/layers/support/Field.js";import l from"@arcgis/core/renderers/SimpleRenderer.js";import m from"@arcgis/core/symbols/MeshSymbol3D.js";import u from"@arcgis/core/symbols/PictureMarkerSymbol.js";import f from"@arcgis/core/symbols/SimpleFillSymbol.js";import y from"@arcgis/core/symbols/SimpleLineSymbol.js";import p from"@arcgis/core/symbols/SimpleMarkerSymbol.js";import d from"dxf-parser";import{geometryTypeToJson as g}from"../json/GeometryJson.js";import{translate as w}from"../locale/language.js";import{INVARIANT as h}from"../locale.js";import{FeatureCollectionLayerExtension as F}from"../mapping/FeatureCollectionLayerExtension.js";import{GroupLayerExtension as S}from"../mapping/GroupLayerExtension.js";import{CaseInsensitiveObservableMap as T}from"../utilities/CaseInsensitiveObservableMap.js";import{Time as N}from"../utilities/Time.js";import{checkArg as O,assertNever as x}from"../utilities/checkArg.js";import{isPoint as M,isMultipoint as D,isPolyline as E,isPolygon as R,isExtent as b}from"../utilities/esri.js";import{parse as A,format as G,DEFAULT_PARSING_FORMATS as _,INVALID_DATE as I}from"../utilities/format/date.js";import{DateFormat as L,NumberFormat as C,TimeFormat as v}from"../utilities/format/formats.js";import{parse as P,format as j}from"../utilities/format/number.js";import{parse as U,format as $,DEFAULT_PARSING_FORMATS as H}from"../utilities/format/time.js";import{project as B,esriToWKT as k,wktToEsri as z,esriWkidToWkt as J,esriWktToWkid as W,esriToGeoJSON as X,geoJSONToEsri as Y}from"../utilities/geometry.js";import{getLogger as q}from"../utilities/log.js";import{isNumeric as Z}from"../utilities/number.js";import{delay as K}from"../utilities/promise.js";import{caseInsensitiveEquals as V}from"../utilities/string.js";import{Feature as Q}from"./Feature.js";import{FeatureSet as ee}from"./FeatureSet.js";import{DxfEntityProcessor as te}from"./support/_dxfConverters.js";const re=["=","-","+","@"],oe='"',ne="\r\n",ae="\n",ie=[..._.map(Ue),"M/d/yy"],se=[...H.map(He).map((e=>e.replace("AM/PM","tt")))],ce=/(\w+)_(point|multipoint|polyline|polygon)z?/;var le;function me(){return q("geocortex.api.data.convert")}!function(e){e.DATE="D",e.NUMBER="N",e.STRING="C",e.BOOLEAN="L"}(le||(le={}));export const FIELD_NAME_REGEX=/[^a-zA-Z\d_]/g;export var GeometryFormat;!function(e){e.NONE="NONE",e.WKT="WKT",e.XY="XY",e.XYZ="XYZ",e.LAT_LON="LAT_LONG",e.GEO_JSON="GEO_JSON",e.ARCGIS_JSON="ARCGIS_JSON"}(GeometryFormat||(GeometryFormat={}));export const geometryTypeHeaders={[GeometryFormat.XYZ]:[["x","y","z"]],[GeometryFormat.XY]:[["x","y"]],[GeometryFormat.LAT_LON]:[["latitude","longitude"],["lat","lon"],["lat","long"]],[GeometryFormat.ARCGIS_JSON]:[["geometry"]],[GeometryFormat.GEO_JSON]:[["geometry"]],[GeometryFormat.WKT]:[["geometry"]]};const ue=[[GeometryFormat.ARCGIS_JSON,be],[GeometryFormat.GEO_JSON,Ae],[GeometryFormat.WKT,Ge]],fe=new Map(ue);export async function uploadDataToFeatureSet(e){const t=await async function(e){const{data:t,includeHeaderRow:o,geometryFormat:n,geometryFields:a,locale:i,numberFormat:s,inSpatialReference:c}=e,l=o?t.slice(1):t;if(n===GeometryFormat.NONE)return{columnIndices:[]};const m=e=>Le(e,i,s),u=(e,t)=>{const o=t===GeometryFormat.XYZ,n=t===GeometryFormat.LAT_LON;return{columnIndices:e,geometries:l.map((t=>{if(t.length>=Math.max(...e)&&Z(t[e[0]]?.raw,i)&&Z(t[e[1]]?.raw,i)&&(!o||Z(t[e[2]]?.raw,i)))return new r({x:m(n?t[e[1]].raw:t[e[0]].raw),y:m(n?t[e[0]].raw:t[e[1]].raw),z:o?m(t[e[2]].raw):0,spatialReference:c})}))}},f=async(e,t)=>({columnIndices:[e],geometries:await Promise.all(l.map((t=>t[e])).map((e=>{if(e?.raw)return t(e.raw.toString(),c)})))}),y=async(e,t)=>{switch(t){case GeometryFormat.NONE:return{columnIndices:[0]};case GeometryFormat.LAT_LON:case GeometryFormat.XYZ:case GeometryFormat.XY:return u(e,t);case GeometryFormat.ARCGIS_JSON:return f(e[0],be);case GeometryFormat.GEO_JSON:return f(e[0],Ae);case GeometryFormat.WKT:return f(e[0],Ge);default:return x(t,new Error(`Unknown geometry format "${t}".`))}};if(n){const e=_e(o?t[0]:t[0].map(((e,t)=>({raw:t.toString()}))),n,o?a:a.map((e=>""+(parseInt(e.match(/\d+/g)[0])-1))));if(o&&void 0===e)throw new Error(`Error parsing file data: Expected geometry columns ${geometryTypeHeaders[n][0].join(",")} are missing for GeometryType.${n}`);return y(e??[0],n)}const[p,d]=await Ce(t,c,o);if(p===GeometryFormat.NONE)return{columnIndices:[]};return d.length>1?u(d,p):f(d[0],fe.get(p))}(e),o=function(e,t){const{data:r,displayField:o,includeHeaderRow:n,inSpatialReference:a,outSpatialReference:i,generatePrimaryKey:s}=e,c={fields:[]},l=e=>!(!t.columnIndices||0===t.columnIndices.length)&&t.columnIndices.includes(e);let{primaryKeyField:m}=e,u=0;for(let t=0;t<r[0].length;t++){if(l(t))continue;const o=Pe(e,t,!s&&!m&&!c.fields.find((e=>"esriFieldTypeOID"===e.type)));let a=r[0][t]?.raw?.toString(),i=a?.replace(FIELD_NAME_REGEX,"_");n&&i||(i="field"+ ++u,a=w("gcx.api.data.convert.import-field-alias",u)),c.fields.push({alias:a,name:i,type:o}),"esriFieldTypeOID"===o&&(m=i)}if(c.spatialReference=i??t.geometries?.[0]?.spatialReference??a,t.geometries?.length){const e=t.geometries.filter((e=>void 0!==e)).map((e=>e.type)),r=e[0];c.geometryType=e.every((e=>e===r))?g(r):void 0}if(!c.fields.find((e=>"esriFieldTypeOID"===e.type))){const e=c.fields.length+1,t=!!c.fields.find((e=>"objectid"===e.name.toLowerCase()));m=t?`OBJECTID_${e}`:"OBJECTID",c.fields.push({name:m,alias:m,type:"esriFieldTypeOID"})}return c.displayField=o??c.fields.find((e=>!V(e.name,m)&&"esriFieldTypeString"===e.type))?.name??c.fields.find((e=>!V(e.name,m)))?.name??m,c.primaryKeyField=m,c}(e,t),n=await async function(e,t,r){const{data:o,includeHeaderRow:n,outFields:a,escapeFormulaChars:i,locale:s,numberFormat:c,dateFormat:l,timeFormat:m}=e,{spatialReference:u}=r,f=[],y=n?o.slice(1):o,p=(e,r)=>!t.columnIndices||0===t.columnIndices.length||!t.columnIndices.includes(r);return await Promise.all(y.map((async(e,o)=>{const n=new Q;for(let t=0;t<r.fields.length;t++){const u=r.fields[t],f=e.filter(p);if(a.includes("*")||a.filter((e=>V(e,u.name))).length>0){let e=await je(f[t]?.raw,u,{escapeFormulaChars:i,dateFormat:l,numberFormat:c,timeFormat:m,locale:s});"esriFieldTypeOID"===u.type&&null===e&&(e=o),n.attributes.set(u.name,e)}}t.geometries&&(n.geometry=await Te(t.geometries[o],u)),f.push(n)}))),f}(e,t,o);return new ee({features:n,schema:o})}export async function toCsv(e,t){O("featureSet",e).isNotMissing();const r=Array.from(e),o={...{useFormattedValues:!1,alwaysQuote:!1,escapeFormulaChars:!0,delimiter:",",dateFormat:L.ROUND_TRIP,timeFormat:v.ROUND_TRIP,geometryFormat:r.some((e=>void 0!==e.geometry&&null!==e.geometry))?GeometryFormat.WKT:GeometryFormat.NONE,includeByteOrderMark:!0,outSpatialReference:a.WGS84,includeHeaderRow:!0,outFields:Fe(e.source),rowDelimiter:navigator.platform?.startsWith("Win")?ne:"\n"},...t},{includeByteOrderMark:n,includeHeaderRow:i,delimiter:s,outFields:c,rowDelimiter:l}=o,m=[];n&&m.push("\ufeff");const u=we(r,o),f=he(r,c,e.schema,!0),y=he(r,c,e.schema,!1);if(i){const e=[];for(const t of u)e.push(Ne(t,o));for(const t of f)e.push(Ne(t,o));for(const t of y)e.push(Ne(t,o));const t=e.join(s)+l;m.push(t)}await Promise.all(r.map((async e=>{const t=[],r=(t,r)=>{const o=xe(e,t,r),n=e.schema.findFieldByName(t)?.type;return Ne(Oe(o,{...r,isDateOnly:"date-only"===n}),r)};t.push(...await async function(e,t){let r=await Se(e,t);t.geometryFormat!==GeometryFormat.XYZ&&t.geometryFormat!==GeometryFormat.XY&&t.geometryFormat!==GeometryFormat.LAT_LON||(r=r.map((e=>void 0===e?"":Oe(e,t))));return r.map((e=>""===e?"":Ne(e,t)))}(e.geometry,o)),t.push(...f.map((e=>r(e,o)))),t.push(...y.map((e=>r(e,o))));const n=`${t.join(s)}${l}`;m.push(n)})));return new Blob(m,{type:"text/plain",endings:"\n"===l||l===ne?"transparent":"native"})}export async function csvToUploadData(e,t){let r;if(O("csvData",e).isNotMissing(),e instanceof Blob){const t=new Promise(((t,r)=>{const o=new FileReader;o.onload=()=>{t(o.result)},o.onerror=()=>{r(o.error)},o.readAsText(e)}));r=await t}else r=e;const o=pe(t),n=o.rowDelimiter||function(e){let t=ae;return Re(e,ne,((r,o)=>(0===r&&o===e.length||(t=ne),!1))),t}(r),a=o.delimiter??function(e,t,r){const o=",";if(0===e.length)return o;const n=[];if(Re(e,t,((t,r)=>(r!==e.length||t!==r)&&(n.push(e.substring(t,r)),n.length<3))),0===n.length)return o;let a=[{delimiter:",",rowsDelimiterOccurrences:[],rowsNumberAdjacentOccurrences:[]},{delimiter:";",rowsDelimiterOccurrences:[]},{delimiter:"|",rowsDelimiterOccurrences:[]},{delimiter:"\t",rowsDelimiterOccurrences:[]},{delimiter:" ",rowsDelimiterOccurrences:[]}].filter((e=>n[0].includes(e.delimiter)));if(0===a.length)return o;for(const e of n)for(const t of a){let o=0,n=0;Re(e,t.delimiter,((a,i)=>{if(i!==e.length&&o++,","===t.delimiter){const t=e.charAt(i-1),o=e.charAt(i+1);Z(t,r)&&Z(o,r)&&n++}return!0})),t.rowsDelimiterOccurrences.push(o),","===t.delimiter&&t.rowsNumberAdjacentOccurrences.push(n)}if(a=a.filter((e=>e.rowsDelimiterOccurrences.every((t=>e.rowsDelimiterOccurrences[0]===t)))).sort(((e,t)=>t.rowsDelimiterOccurrences[0]-e.rowsDelimiterOccurrences[0])),a.length>1&&","===a[0].delimiter&&null!=r&&r!==h){const e=a[0];if(null!=e&&","===e.delimiter&&","===Intl.NumberFormat(r).formatToParts(1.1).find((e=>"decimal"===e.type))?.value)for(let t=0;t<e.rowsDelimiterOccurrences.length;t++)if(e.rowsDelimiterOccurrences[t]<=e.rowsNumberAdjacentOccurrences[t]){a=a.filter((e=>","!==e.delimiter));break}}if(0===a.length)return o;return a[0].delimiter}(r,n,t.locale),i=function(e,t,r){const o=[],n=(e,t)=>{const o=[];return Re(e,r,((r,n)=>{const a=e.substring(r,n);return o.push({raw:Ee(a,t,o.length)}),!0})),o};if(Re(e,t,((t,r)=>{const a=e.substring(t,r);return a.length>0&&o.push(n(a,o.length)),!0})),o.length){const e=o[0].length;o.forEach(((t,r)=>{if(t.length!==e)throw new Error(`Detected invalid CSV: Row ${r} does not have expected number of columns: ${e}`)}))}return o}(r,n,a);let{geometryFormat:s,geometryFields:c}=t;if(!s){const[e,t]=await Ce(i,o.inSpatialReference,o.includeHeaderRow);s=e,c=t.map((e=>o.includeHeaderRow?i[0][e]?.raw??w("gcx.api.data.convert.import-field-alias",(e+1).toString()):w("gcx.api.data.convert.import-field-alias",(e+1).toString())))}return{data:i,...o,geometryFormat:s,geometryFields:c}}export async function csvToFeatureSet(e,t){const r=pe(t);return uploadDataToFeatureSet(await csvToUploadData(e,r))}export async function toXLSX(e,t){O("featureSet",e).isNotMissing();const r=Array.from(e),o={...{useFormattedValues:!1,includeHeaderRow:!0,escapeFormulaChars:!0,geometryFormat:r.some((e=>void 0!==e.geometry&&null!==e.geometry))?GeometryFormat.WKT:GeometryFormat.NONE,outFields:Fe(e.source),outSpatialReference:a.WGS84,dateFormat:L.DEFAULT,timeFormat:v.DEFAULT,numberFormat:C.DEFAULT,sheetName:"sheet1"},...t},{outFields:n,includeHeaderRow:i,dateFormat:s,timeFormat:c,numberFormat:l}=o,m=we(r,o),u=he(r,n,e.schema,!0),f=he(r,n,e.schema,!1),y=await import("xlsx"),p=y.utils.sheet_new();let d=!1;if(i){const t=m.concat(u).concat(function(e,t){const r=t?.schema?.fieldExtensions.initializedItems.map((e=>e.field));return e.map((e=>r?.find((t=>V(t.name,e)))?.alias??e))}(f,e.source));d=!0,y.utils.sheet_add_aoa(p,[t],{cellDates:!0})}await Promise.all(r.map((async e=>{const t=[],r=new Set,n=new Set;t.push(...await Se(e.geometry,o));for(const r of u){const n=ke(e.attributes.get(r),o);t.push(n)}for(const a of f){const i=xe(e,a,o);if(i instanceof N){const o=e.schema.findFieldByName(a);"time-only"===o?.type&&r.add(t.length)}else if(i instanceof Date){const r=e.schema.findFieldByName(a);"date-only"===r?.type&&n.add(t.length)}const s=ke(i,o);t.push(s)}if(!t.every((e=>"string"!=typeof e||e.length<=32767)))return void me().warn(`toXLSX cell limit exceeded, feature (${e.primaryKey??e.id}) omitted.`);y.utils.sheet_add_aoa(p,[t],{cellDates:!0,origin:d?-1:void 0}),d=!0;const a=y.utils.decode_range(p["!ref"]);for(let e=a.s.c;e<=a.e.c;e++){const t=p[y.utils.encode_cell({r:a.e.r,c:e})];"d"===t.t?r.has(e)?t.z=He(c??v.ROUND_TRIP):n.has(e)?t.z=$e(s??L.ROUND_TRIP):t.z=Ue(s??L.ROUND_TRIP):"n"===t.t&&(t.z=Be(l))}})));const g={SheetNames:[],Sheets:{}};g.SheetNames.push(o.sheetName),g.Sheets[o.sheetName]=p;const w=y.write(g,{type:"binary",bookType:"xlsx",compression:!0,bookSST:!0,cellDates:!0}),h=new Uint8Array(w.length);for(let e=0;e<w.length;e++)h[e]=w.charCodeAt(e);return new Blob([h.buffer],{type:"text/plain"})}export async function xlsxToUploadData(e,t){O("xlsxData",e).isNotMissing();const r=de(t),o=await async function(e,t){const r=await import("xlsx"),o=new Promise(((o,n)=>{const a=new FileReader;a.onload=()=>{const e=new Uint8Array(a.result);let n="";for(const t of e)n+=String.fromCharCode(t);const i=r.read(n,{type:"binary",cellDates:!0}),s=t.sheetName||i.SheetNames[0],c=i.Sheets[s];o(c)},a.onerror=()=>{n(a.error)},a.readAsArrayBuffer(e)})),n=await o,a=r.utils.decode_range(n["!ref"]),i=[];for(let e=a.s.r;e<=a.e.r;e++){const t=[];for(let o=a.s.c;o<=a.e.c;o++){const a=n[`${r.utils.encode_cell({r:e,c:o})}`];a&&"d"===a.t&&a.v instanceof Date&&(a.v=new Date(a.v.getTime()+6e4*a.v.getTimezoneOffset())),t.push(a?{raw:a.v,formatted:"s"===a.t?void 0:a.w}:{raw:""})}i.push(t)}return i}(e,r);let{geometryFormat:n,geometryFields:a}=t;if(!n){const[e,t]=await Ce(o,r.inSpatialReference,r.includeHeaderRow);n=e,a=t.map((e=>r.includeHeaderRow?o[0][e]?.raw.toString()??w("gcx.api.data.convert.import-field-alias",(e+1).toString()):w("gcx.api.data.convert.import-field-alias",(e+1).toString())))}return{data:o,...r,geometryFormat:n,geometryFields:a}}export async function xlsxToFeatureSet(e,t){O("xlsxData",e).isNotMissing();const r=de(t);return uploadDataToFeatureSet(await xlsxToUploadData(e,r))}export function kmlHexToEsriColor(t){return e.fromHex(`#${t.match(/.{2}/g).reverse().join("")}`)}export function parseKMLCoordinates(e){return e.trim().split(/\s+/).map((e=>{const[t,r,o]=e.split(",").map(Number);return{x:t,y:r,z:o}}))}export function parseKMLSymbol(t,r,o){if(t){const r=t.querySelector("IconStyle > Icon > href")?.textContent;if(r)return new u({url:r,width:32,height:32});const o=t.querySelector("PolyStyle");if(o){const t=o.querySelector("color")?.textContent,r=t?kmlHexToEsriColor(t):new e([0,0,0,1]);return new f({color:r,outline:{color:[0,0,0,.5],width:1}})}const n=t.querySelector("LineStyle");if(n){const t=n.querySelector("color")?.textContent,r=t?kmlHexToEsriColor(t):new e([0,0,0,1]),o=parseFloat(n.querySelector("width")?.textContent||"1");return new y({color:r,width:o})}}return getDefaultSymbol(o,"polygon"===r?"polygon":"point"===r?"point":"polyline")}export async function toShapefile(e,t){O("featureSet",e).isNotMissing();const[{default:r},o]=await Promise.all([import("jszip"),import("../forked-libs/shp-write/index.js")]),n=Array.from(e),i={...{useFormattedValues:!1,outFields:Fe(e.source),fileName:e.title||"export"},...t},{outFields:s,outSpatialReference:c,fileName:l}=i,m=e=>e.geometry.hasZ||e.geometry.hasM,u=new Map,f=n.filter((e=>M(e.geometry)));u.set("POINTZ",f.filter(m)),u.set("POINT",f.filter((e=>!m(e))));const y=n.filter((e=>D(e.geometry)));u.set("MULTIPOINTZ",y.filter(m)),u.set("MULTIPOINT",y.filter((e=>!m(e))));const p=n.filter((e=>E(e.geometry)));u.set("POLYLINEZ",p.filter(m)),u.set("POLYLINE",p.filter((e=>!m(e))));const d=n.filter((e=>R(e.geometry)||b(e.geometry)));u.set("POLYGONZ",d.filter(m)),u.set("POLYGON",d.filter((e=>!m(e))));const g=he(n,s,e.schema,!0);let w=he(n,s,e.schema,!1);w=g.concat(w);const h=new r,F=Array.from(u.keys()).filter((e=>u.get(e).length>0));await Promise.all(F.map((async t=>{const r=u.get(t),n=await Promise.all(r.map((e=>Te(e.geometry,c)))),s=await async function(e){const{wkid:t,wkt:r}=e[0].spatialReference;if(!e.every((e=>e.spatialReference.wkid===t&&e.spatialReference.wkt===r)))throw new Error("Cannot create shapefile that contains geometries with different spatial references.");return r??await J(t??a.WGS84.wkid)}(n),m=i.useFormattedValues?Object.assign({},...w.map((e=>({[e]:le.STRING})))):function(e,t,r,o){const n={};for(const a of t){if(e.some((e=>Me(e,a)))){n[a]=le.STRING;continue}const t=r?r.fields.find((e=>V(e.name,a))):void 0;if(t){switch(t.type){case"oid":case"double":case"integer":case"single":case"small-integer":case"big-integer":n[a]=le.NUMBER;break;case"date":case"timestamp-offset":n[a]=o?le.NUMBER:le.DATE;break;default:n[a]=le.STRING}continue}const i=(e,t)=>e.attributes.get(t)??e.presentableAttributes.get(t);e.every((e=>i(e,a)instanceof Date||void 0===i(e,a)))&&e.some((e=>i(e,a)instanceof Date))?n[a]=o?le.NUMBER:le.DATE:e.every((e=>"number"==typeof i(e,a)||void 0===i(e,a)))&&e.some((e=>"number"==typeof i(e,a)))?n[a]=le.NUMBER:e.every((e=>"boolean"==typeof i(e,a)||void 0===i(e,a)))&&e.some((e=>"boolean"==typeof i(e,a)))?n[a]=le.BOOLEAN:n[a]=le.STRING}return n}(r,w,e.schema,"timestamp"===i.dateFormat),f=function(e){return e.map((e=>{if(M(e)){const{x:t,y:r,z:o,m:n}=e,a=[t,r];return e.hasZ&&a.push(o),e.hasM&&a.push(n),ze(a,e)}if(D(e))return Je(e.points,e);if(E(e))return We(e.paths,e);if(R(e))return We(e.rings,e);if(b(e)){const t=[e.xmin,e.ymax];return[[t,[e.xmax,e.ymax],[e.xmax,e.ymin],[e.xmin,e.ymin],t]]}throw new Error("Unsupported geometry type.")}))}(n),y=function(e,t,r,o){const n=[];for(const a of e){const e={};for(const n of t){let t=xe(a,n,o);if(null==t&&(t=""),o.useFormattedValues)t=t.toString();else{t=Xe(t,r[n],{...o,isDateOnly:"date-only"===a.schema.findFieldByName(n)?.type})}e[n.replaceAll(".","_")]=t}n.push(e)}return n}(r,w,m,i);o.write(y,t,f,((e,r)=>{const o=F.length>1?`${l}_${t.toLowerCase()}`:l;h.file(`${o}.shp`,r.shp.buffer,{binary:!0}),h.file(`${o}.shx`,r.shx.buffer,{binary:!0}),h.file(`${o}.dbf`,r.dbf.buffer,{binary:!0}),h.file(`${o}.prj`,s)}))})));const S=await h.generateAsync({type:"uint8array"});return new Blob([S.buffer],{type:"text/plain"})}export async function kmlToLayerExtensions(e){O("blob",e).isNotMissing();const a=await e.text(),m=(new DOMParser).parseFromString(a,"application/xml"),u=function(e,a){const f={};m.querySelectorAll("Style").forEach((e=>{f[`#${e.id}`]=e}));const y=e.querySelector(":scope > name")?.textContent??"Unnamed Container",p=new S({layer:new s({title:y})});e.querySelectorAll(":scope > Placemark").forEach(((e,s)=>{const m=e.querySelector("name")?.textContent??"",u=e.querySelector("description")?.textContent??"",d=function(e){const t=e.querySelector("Point > coordinates"),a=e.querySelector("LineString > coordinates"),i=e.querySelector("Polygon");if(t?.textContent){const[e]=parseKMLCoordinates(t.textContent.replace(/ /g,""));return new r(e)}if(a?.textContent)return new n({paths:[parseKMLCoordinates(a.textContent).map((({x:e,y:t})=>[e,t]))]});if(i?.textContent){const e=i.querySelector("outerBoundaryIs > LinearRing > coordinates");if(e?.textContent){const t=[parseKMLCoordinates(e.textContent).map((({x:e,y:t})=>[e,t]))];return new o({rings:t})}}return}(e);if(d){const r=e.querySelector("styleUrl")?.textContent,o=parseKMLSymbol(r?f[r]:e.querySelector("Style"),d.type,a),n=new i({displayField:"name",title:m,source:[new t({geometry:d,attributes:{name:m,description:u,OBJECTID:y+s}})],renderer:new l({symbol:o}),fields:[new c({name:"OBJECTID",type:"oid",alias:"OBJECTID"}),new c({name:"name",type:"string",alias:"name"})]});u&&n.fields.push(new c({name:"description",type:"string",alias:"description",defaultValue:""}));const g=new F({layer:n});p.layerExtensions.add(g)}}));return e.querySelectorAll(":scope > Folder, :scope > Document").forEach(((e,t)=>{const r=u(e,t);p.layerExtensions.add(r)})),p},f=[];return m.querySelectorAll("kml > Document, kml > Folder").forEach(((e,t)=>{const r=u(e,t);r.layerExtensions.length&&f.push(r)})),f}export async function dxfToLayerExtensions(e,t,r){const{inputSpatialReference:o,outputSpatialReference:n}=t;O("options.dxfBlob",e).isNotMissing(),O("options.inputSpatialReference",o).isNotMissing(),O("options.outputSpatialReference",n).isNotMissing();const a=new te(o,n,r),i=a.getContext(),c=await e.text(),l=new d;await K();try{const e=l.parseSync(c);if(!e)throw new Error("DXF parsing failed: parser returned null");i.dxf=e}catch(e){throw e instanceof Error?e:new Error(String(e))}const m=e instanceof File?e.name:"dxf-layer",u=m.replace(/[^a-zA-Z0-9_.-]/g,"_");if(i.fileName=m,i.sanitizedFileName=u,i.subLayers=await a.processAll(),!i.subLayers||0===i.subLayers.length)return[];const f=new s({id:`dxf-group-${u}-${(new Date).getTime()}`,title:m,visible:!0}),y={layer:f,visibilityMode:"independent"};return f.layers.addMany(i.subLayers),[new S(y)]}export async function shapefileToUploadData(e,t){O("shapefileData",e).isNotMissing();const o=ge(t),n=new Promise(((t,r)=>{const o=new FileReader;o.onload=()=>{t(o.result)},o.onerror=()=>{r(o.error)},o.readAsArrayBuffer(e)})),[{default:i},{default:s}]=await Promise.all([import("jszip"),import("shpjs")]),c=await n,l=await i.loadAsync(new Uint8Array(c)),m=new T;l.forEach(((e,t)=>{t&&m.set(t.name,t)}));const u=l.filter((()=>!0)).map((e=>e.name));let f,y=u.filter((e=>e.endsWith(".shp"))).map((e=>e.substring(0,e.length-4)));if(y=function(e){if(!e.length)return[];let t=e[0];const r=t.match(ce);return r?(t=r[1],e.filter((e=>{const r=e.match(ce);return r&&r[1]===t}))):[t]}(y),u.some((e=>e.endsWith(".prj")))&&!y.every((e=>m.has(`${e}.prj`))))throw new Error("Shapefile zip must contain the same prj file for each separate shapefile");await Promise.all(u.filter((e=>e.endsWith(".prj"))).map((async e=>{const t=await l.file(e).async("string");if(f){if(t!==f)throw new Error("Shapefile zip must contain the same prj file for each separate shapefile")}else f=t})));let p=[],d=[];for(const e of y){if(!m.has(`${e}.shp`)||!m.has(`${e}.shx`)||!m.has(`${e}.dbf`))throw new Error("Shapefile must contain shp, shx, and dbf files.");const t=s.parseShp(await m.get(`${e}.shp`).async("uint8array")),r=s.parseDbf(await m.get(`${e}.dbf`).async("uint8array"));if(r.length!==t.length)throw new Error("Shapefile must contain shp, shx, and dbf files.");p=p.concat(r),d=d.concat(t)}const g=await Promise.all(d.map((e=>async function(e,t){const o=M(e)?function(e){O("geometry.coordinates",e.type).matches("Point"),O("geometry.coordinates",e.coordinates).satisfies((e=>"number"==typeof e||Array.isArray(e)));const[t,o,n]=e.coordinates,i=new r({x:t,y:o,spatialReference:a.WGS84});if(Array.isArray(n)){const[e,t]=n;!e&&!t||e?i.z=e:i.m=t}return i}(e):await Y(e);if(t){let e;try{const r=await W(t);e=new a({wkid:P(r)})}catch{}e||(e=new a({wkt:t})),o.spatialReference=e}return o}(e,f)))),w=geometryTypeHeaders[GeometryFormat.ARCGIS_JSON][0][0];p.forEach(((e,t)=>e[w]=JSON.stringify(g[t].toJSON())));return{data:function(e){const t=e.map((e=>Object.keys(e))).reduce(((e,t)=>e.concat(t.filter((t=>!e.includes(t))))),[]);return[t.map((e=>({raw:e}))),...e.map((e=>t.map((t=>({raw:e[t]})))))]}(p),...o,includeHeaderRow:!0,geometryFormat:GeometryFormat.ARCGIS_JSON,geometryFields:[w],inSpatialReference:g[0]?.spatialReference??a.fromJSON({wkid:4326})}}export async function shapefileToFeatureSet(e,t){O("shapefileData",e).isNotMissing();const r=ge(t);return uploadDataToFeatureSet(await shapefileToUploadData(e,r))}export function getDefaultSymbol(e,t){const r=e%8;let o=["#FFDBFF","#88D6FF","#7F9FC3","#FF8200","#F34A53","#76E3B9","#E7BFFF","#FFC467"][r],n=["#EF3786","#005A99","#2D5070","#790C00","#4C0000","#006543","#6244A9","#904200"][r];if(Math.floor(e/8)%2!=0){const e=o;o=n,n=e}switch(t){case"point":case"multipoint":return new p({color:o,outline:{color:n}});case"polyline":return new y({color:o,width:"2"});case"polygon":return new f({color:o,outline:{color:n}});case"mesh":return new m({symbolLayers:[{type:"fill",material:{color:o},outline:{color:n}}]})}}function ye(e){return{escapeFormulaChars:!0,outFields:["*"],generatePrimaryKey:!1,locale:h,detectOid:!e?.primaryKeyField}}function pe(e){return{...{includeHeaderRow:!0,inSpatialReference:a.WGS84,...ye(e)},...e}}function de(e){return{...{includeHeaderRow:!0,inSpatialReference:a.WGS84,...ye(e)},...e}}function ge(e){return{...{...ye(e)},...e}}function we(e,t){return t.geometryFormat===GeometryFormat.XYZ?["x","y","z"]:t.geometryFormat===GeometryFormat.XY?["x","y"]:t.geometryFormat===GeometryFormat.LAT_LON?["latitude","longitude"]:t.geometryFormat===GeometryFormat.NONE?[]:["geometry"]}function he(e,t,r,o){const n=r.fields.filter((e=>"oid"===e.type)).map((e=>e.name)).toArray();if(o)return n;if(t&&!t.includes("*"))return t.filter((e=>!n.includes(e)));{const t=r.fields.filter((e=>"oid"!==e.type)).map((e=>e.name)).toArray();let o=[];for(const r of e)for(const e of r.attributes.keys())t.includes(e)||n.includes(e)||o.includes(e)||o.push(e);return o=o.sort(),t.concat(o)}}function Fe(e){if(!e)return["*"];const t=e.featureSettings.popupTemplate?.content;return(Array.isArray(t)?t.find((e=>"fields"===e.type))?.fieldInfos?.filter((e=>e.visible))?.map((e=>e.fieldName)):void 0)??e.featureSettings.popupTemplate?.fieldInfos?.filter((e=>e.visible))?.map((e=>e.fieldName))??["*"]}async function Se(e,t){const r=await Te(e,t.outSpatialReference);if(t.geometryFormat===GeometryFormat.XYZ){if(!r)return["","",""];if(!M(r))throw new Error("Cannot use geometry format XYZ with non-point geometry");return[r.x,r.y,r.z]}if(t.geometryFormat===GeometryFormat.XY){if(!r)return["",""];if(!M(r))throw new Error("Cannot use geometry format XY with non-point geometry");return[r.x,r.y]}if(t.geometryFormat===GeometryFormat.LAT_LON){if(!r)return["",""];if(!M(r))throw new Error("Cannot use geometry format LAT_LONG with non-point geometry");return[r.y,r.x]}return t.geometryFormat===GeometryFormat.ARCGIS_JSON?r?[JSON.stringify(r.toJSON())]:[""]:t.geometryFormat===GeometryFormat.WKT?r?[await k(r)]:[""]:t.geometryFormat===GeometryFormat.GEO_JSON?r?[JSON.stringify(await X(r))]:[""]:[]}async function Te(e,t){return e?.spatialReference&&!e.spatialReference.equals(t)&&t?(await B([e],t))[0]:e}function Ne(e,t){const r=[t.delimiter,oe,"\r","\n",t.rowDelimiter];if(t.alwaysQuote||r.some((t=>e.includes(t)))){const t=e.replace(new RegExp(oe,"g"),`${oe}${oe}`);return`${oe}${t}${oe}`}return e}function Oe(e,t){if(null==e)return"";if(!t.useFormattedValues){if("number"==typeof e){const r=t.numberFormat||C.ROUND_TRIP;return j(r,e)}if(e instanceof Date)return"timestamp"===t.dateFormat?e.getTime().toString():G({format:t.dateFormat,timeZone:"UTC",isDateOnly:t.isDateOnly},e);if(e instanceof N)return $({format:t.timeFormat},e)}let r=e.toString();return t.escapeFormulaChars&&(r=De(r)),r}function xe(e,t,r){if(r.useFormattedValues||Me(e,t))return e.presentableAttributes.get(t)??e.attributes.get(t);const o=e.schema.findFieldByName(t)?.type;if(null!=o)switch(o){case"date":case"date-only":case"timestamp-offset":{const r=A(e.attributes.get(t));if(!isNaN(r.getTime()))return r;break}case"time-only":{const r=U(e.attributes.get(t));if(r.isValid)return r;break}}return e.attributes.get(t)??e.presentableAttributes.get(t)}function Me(e,t){return!!V(t,e.schema.typeIdField)||("coded-value"===e.type?.domains?.[t]?.type||"coded-value"===e.schema.findFieldByName(t)?.domain?.type)}function De(e){for(const t of re)if(e.startsWith(t))return`\t${e}`;return e}function Ee(e,t,r){const o=e.startsWith(oe),n=e.endsWith(oe);if(o&&!n||!o&&n)throw new Error(`Detected invalid CSV: Missing opening or closing quote for value at row:${t} column:${r}`);const a=o?e.substring(1,e.length-1):e;let i=-1;return Re(a,oe,((e,o)=>{if(o===a.length)return!0;if(i<0){if(o!==a.length)return i=o,!0}else if(o===i+1)return i=-1,!0;throw new Error(`Detected invalid CSV: Non-escaped quote for value at row:${t} column:${r}`)})),a.replace(new RegExp(`${oe}${oe}`,"g"),oe)}function Re(e,t,r){let o,n=!1,a=0,i=0;for(;o=e.indexOf(t,a),!(o<0);){for(let t=a;t<o;)e.substring(t).startsWith(oe)?(n=!n,t+=1):t++;const s=o+t.length;if(!n){const e=r(i,o);if(i=s,!e)return}a=s}r(i,e.length)}async function be(e,t){const r=JSON.parse(e),o=(await import("@arcgis/core/geometry/support/jsonUtils")).fromJSON(r);return r.spatialReference||(o.spatialReference=t),o}async function Ae(e,t){const r=await Y(JSON.parse(e));return r.spatialReference=t,r}async function Ge(e,t){const r=await z(e);return r.spatialReference=t,r}function _e(e,t,r){const o=r?[r]:geometryTypeHeaders[t];for(const t of o){const r=t.map((t=>e.map((e=>e?.raw?.toString().trim().toLowerCase())).indexOf(t.trim().toLowerCase())));if(r.every((e=>e>=0)))return r}}async function Ie(e,t){return(await Promise.all(e.map((async(e,r)=>{const o=e?.raw;if("string"==typeof o&&""!==o)try{return await t(o,void 0),r}catch{return}})))).find((e=>void 0!==e))}function Le(e,t,r){return"inv"===t?"string"==typeof e?parseFloat(e.replaceAll(",","")):e:P({locale:t,format:r},e)}async function Ce(e,t,r){const o=r?e.slice(1):e;if(r){const r=_e(e[0],GeometryFormat.ARCGIS_JSON);if(void 0!==r)for(const[e,n]of ue){try{await ve(r[0],n,t,o)}catch{continue}return[e,[r[0]]]}const n=[GeometryFormat.XYZ,GeometryFormat.XY,GeometryFormat.LAT_LON];for(const t of n){const r=_e(e[0],t);if(void 0!==r)return[t,r]}}for(const[e,r]of ue){const n=await Ie(o[0],r);if(void 0!==n){try{await ve(n,r,t,o)}catch{continue}return[e,[n]]}}return[GeometryFormat.NONE,[]]}async function ve(e,t,r,o){return{columnIndices:[e],geometries:await Promise.all(o.map((t=>t[e])).map((e=>{if(e?.raw)return t(e.raw.toString(),r)})))}}function Pe(e,t,r){let o=!1,n=!0,a=!0,i=!0,s=!0,c=!0;const l=new Set,{data:m,includeHeaderRow:u,dateFormat:f,timeFormat:y,primaryKeyField:p,locale:d}=e,g=u?m[0]:[],w=u?m.slice(1):m;for(const e of w){const r=e[t];r?.raw&&(l.add(r.raw),o=!0,n&&(n=Z(r.raw,d)||Number.isNaN(r.raw)),a&&(a=r.raw instanceof Date||A(f||_,r.raw)!==I),s&&(s=A(f||ie,r.formatted)!==I),i&&(i=r.raw instanceof N||U(y||H,r.raw).isValid),c&&(c=U({format:y||se,locale:"en"},r.formatted).isValid))}const h=l.size===w.length;return p&&g[t]?.raw===p||r&&o&&h&&n?"esriFieldTypeOID":o&&c?"esriFieldTypeTimeOnly":o&&s?"esriFieldTypeDate":o&&n?"esriFieldTypeDouble":o&&i?"esriFieldTypeTimeOnly":o&&a?"esriFieldTypeDate":"esriFieldTypeString"}async function je(e,t,r){const{escapeFormulaChars:o,locale:n,numberFormat:a,dateFormat:i,timeFormat:s}=r;if("esriFieldTypeDouble"===t.type||"esriFieldTypeOID"===t.type)return"number"==typeof e?e:e?Le(e,n,a):null;if("esriFieldTypeDate"===t.type){if(e instanceof Date)return e.getTime();if("number"==typeof e){const t=(await import("xlsx")).SSF.parse_date_code(e);return t?new Date(t.y,t.m-1,t.d,t.H,t.M,t.S).getTime():void 0}return""===e?null:A({locale:n,format:i},e).getTime()}if("esriFieldTypeTimeOnly"===t.type){if(e instanceof N)return e.toString();if(e instanceof Date)return new N(e).toString();if("number"==typeof e){const t=(await import("xlsx")).SSF.parse_date_code(e);return t?new N(`${t.H.toString().padStart(2,"0")}:${t.M.toString().padStart(2,"0")}:${t.S.toString().padStart(2,"0")}`).toString():void 0}return""===e?null:U({locale:n,format:s},e).toString()}const c=e?.toString()??"";if(o&&c.startsWith("\t"))for(const e of re)if(c.length>1&&c.charAt(1)===e)return c.substring(1);return c}function Ue(e){switch(e){case L.DATE_SHORT:return"dd/MM/yyyy";case L.DATE_LONG:return"MMMM d, yyyy";case L.TIME_SHORT:return"h:mm AM/PM";case L.TIME_LONG:return"h:mm:ss AM/PM";case L.DATE_TIME_SHORT:case L.DEFAULT:return"MMM d yyyy h:mm AM/PM";case L.DATE_TIME_LONG:return"MMMM d yyyy h:mm AM/PM";case L.FULL:return"dddd, MMMM d yyyy h:mm AM/PM";case L.ISO_8601:case L.ROUND_TRIP:return'yyyy-MM-dd"T"HH:mm:ss';default:{const t=e.replace(/tt/g,"AM/PM");return t.includes("z")&&me().warn("Warning: Excel will not recognize timezone format 'z', 'zz', or 'zzz'"),t.includes("h")&&!t.includes("AM/PM")&&me().warn("Warning: Excel will interpret 'h' as 'H' if the format does not have an AM/PM designator"),t}}}function $e(e){switch(e){case L.DATE_SHORT:return"dd/MM/yyyy";case L.DATE_LONG:return"MMMM d, yyyy";case L.DATE_TIME_SHORT:case L.DEFAULT:return"MMM d yyyy";case L.DATE_TIME_LONG:return"MMMM d yyyy";case L.FULL:return"dddd, MMMM d yyyy";case L.ISO_8601:case L.ROUND_TRIP:return"yyyy-MM-dd";default:return e.replace(/TtZzHhmSsUua/g,"")}}function He(e){switch(e){case v.TIME_SHORT:return"h:mm AM/PM";case v.TIME_LONG:return"h:mm:ss AM/PM";case v.ISO_8601:case v.ROUND_TRIP:return"HH:mm:ss";default:{const t=e.replace(/tt/g,"AM/PM");return t.includes("h")&&!t.includes("AM/PM")&&me().warn("Warning: Excel will interpret 'h' as 'H' if the format does not have an AM/PM designator"),t}}}function Be(e){switch(e){case C.ACCOUNTING:return'_("$"* #,##0.00_);_("$"* (#,##0.00);_("$"* "-"??_);_(@_)';case C.CURRENCY:return'"$"#,##0.00';case C.FIXED_POINT:case C.DEFAULT:return"0.0000";case C.NUMBER:return"#,##0.0000";case C.PERCENT:return"0%";case C.ROUND_TRIP:return"0.00000";default:return e}}function ke(e,t){if(null==e)return"";if(!t.useFormattedValues){if("number"==typeof e)return e;if(e instanceof Date)return"timestamp"===t.dateFormat?e.getTime():e;if(e instanceof N)return e.toDate()}let r=e.toString();return t.escapeFormulaChars&&(r=De(r)),r}function ze(e,t){return 3===e.length&&!t.hasZ&&t.hasM?[e[0],e[1],void 0,e[2]]:e}function Je(e,t){return e.map((e=>ze(e,t)))}function We(e,t){return e.map((e=>Je(e,t)))}function Xe(e,t,r){switch(t){case le.NUMBER:return e instanceof Date?e.getTime():P(e);case le.STRING:return e instanceof Date?G({format:r.dateFormat??L.ROUND_TRIP,timeZone:"UTC",isDateOnly:r.isDateOnly},e):e instanceof N?$({format:r.timeFormat??v.ROUND_TRIP},e):"number"==typeof e?j(r.numberFormat??C.DEFAULT,e):e.toString();case le.BOOLEAN:return!!e;case le.DATE:return A(e);default:return e.toString()}}
1
+ import e from"@arcgis/core/Color.js";import t from"@arcgis/core/Graphic.js";import r from"@arcgis/core/geometry/Point";import o from"@arcgis/core/geometry/Polygon.js";import n from"@arcgis/core/geometry/Polyline.js";import a from"@arcgis/core/geometry/SpatialReference";import i from"@arcgis/core/layers/FeatureLayer.js";import s from"@arcgis/core/layers/GroupLayer.js";import l from"@arcgis/core/layers/support/Field.js";import c from"@arcgis/core/renderers/SimpleRenderer.js";import m from"@arcgis/core/renderers/UniqueValueRenderer.js";import u from"@arcgis/core/renderers/support/UniqueValueInfo.js";import f from"@arcgis/core/symbols/MeshSymbol3D.js";import y from"@arcgis/core/symbols/PictureMarkerSymbol.js";import p from"@arcgis/core/symbols/SimpleFillSymbol.js";import d from"@arcgis/core/symbols/SimpleLineSymbol.js";import g from"@arcgis/core/symbols/SimpleMarkerSymbol.js";import w from"dxf-parser";import{geometryTypeToJson as h}from"../json/GeometryJson.js";import{translate as F}from"../locale/language.js";import{INVARIANT as S}from"../locale.js";import{FeatureCollectionLayerExtension as T}from"../mapping/FeatureCollectionLayerExtension.js";import{GroupLayerExtension as N}from"../mapping/GroupLayerExtension.js";import{CaseInsensitiveObservableMap as O}from"../utilities/CaseInsensitiveObservableMap.js";import{Time as D}from"../utilities/Time.js";import{checkArg as b,assertNever as x}from"../utilities/checkArg.js";import{isPoint as M,isMultipoint as E,isPolyline as R,isPolygon as A,isExtent as I}from"../utilities/esri.js";import{parse as G,format as _,DEFAULT_PARSING_FORMATS as C,INVALID_DATE as L}from"../utilities/format/date.js";import{DateFormat as v,NumberFormat as P,TimeFormat as j}from"../utilities/format/formats.js";import{parse as U,format as $}from"../utilities/format/number.js";import{parse as H,format as B,DEFAULT_PARSING_FORMATS as J}from"../utilities/format/time.js";import{project as z,esriToWKT as k,wktToEsri as W,esriWkidToWkt as X,esriWktToWkid as q,esriToGeoJSON as Y,geoJSONToEsri as Z}from"../utilities/geometry.js";import{getLogger as K}from"../utilities/log.js";import{isNumeric as V}from"../utilities/number.js";import{delay as Q}from"../utilities/promise.js";import{caseInsensitiveEquals as ee}from"../utilities/string.js";import{Feature as te}from"./Feature.js";import{FeatureSet as re}from"./FeatureSet.js";import{DxfEntityProcessor as oe}from"./support/_dxfConverters.js";const ne=["=","-","+","@"],ae='"',ie="\r\n",se="\n",le=[...C.map(He),"M/d/yy"],ce=[...J.map(Je).map((e=>e.replace("AM/PM","tt")))],me=/(\w+)_(point|multipoint|polyline|polygon)z?/;var ue;function fe(){return K("geocortex.api.data.convert")}!function(e){e.DATE="D",e.NUMBER="N",e.STRING="C",e.BOOLEAN="L"}(ue||(ue={}));export const FIELD_NAME_REGEX=/[^a-zA-Z\d_]/g;export var GeometryFormat;!function(e){e.NONE="NONE",e.WKT="WKT",e.XY="XY",e.XYZ="XYZ",e.LAT_LON="LAT_LONG",e.GEO_JSON="GEO_JSON",e.ARCGIS_JSON="ARCGIS_JSON"}(GeometryFormat||(GeometryFormat={}));export const geometryTypeHeaders={[GeometryFormat.XYZ]:[["x","y","z"]],[GeometryFormat.XY]:[["x","y"]],[GeometryFormat.LAT_LON]:[["latitude","longitude"],["lat","lon"],["lat","long"]],[GeometryFormat.ARCGIS_JSON]:[["geometry"]],[GeometryFormat.GEO_JSON]:[["geometry"]],[GeometryFormat.WKT]:[["geometry"]]};const ye=[[GeometryFormat.ARCGIS_JSON,Ie],[GeometryFormat.GEO_JSON,Ge],[GeometryFormat.WKT,_e]],pe=new Map(ye);export async function uploadDataToFeatureSet(e){const t=await async function(e){const{data:t,includeHeaderRow:o,geometryFormat:n,geometryFields:a,locale:i,numberFormat:s,inSpatialReference:l}=e,c=o?t.slice(1):t;if(n===GeometryFormat.NONE)return{columnIndices:[]};const m=e=>ve(e,i,s),u=(e,t)=>{const o=t===GeometryFormat.XYZ,n=t===GeometryFormat.LAT_LON;return{columnIndices:e,geometries:c.map((t=>{if(t.length>=Math.max(...e)&&V(t[e[0]]?.raw,i)&&V(t[e[1]]?.raw,i)&&(!o||V(t[e[2]]?.raw,i)))return new r({x:m(n?t[e[1]].raw:t[e[0]].raw),y:m(n?t[e[0]].raw:t[e[1]].raw),z:o?m(t[e[2]].raw):0,spatialReference:l})}))}},f=async(e,t)=>({columnIndices:[e],geometries:await Promise.all(c.map((t=>t[e])).map((e=>{if(e?.raw)return t(e.raw.toString(),l)})))}),y=async(e,t)=>{switch(t){case GeometryFormat.NONE:return{columnIndices:[0]};case GeometryFormat.LAT_LON:case GeometryFormat.XYZ:case GeometryFormat.XY:return u(e,t);case GeometryFormat.ARCGIS_JSON:return f(e[0],Ie);case GeometryFormat.GEO_JSON:return f(e[0],Ge);case GeometryFormat.WKT:return f(e[0],_e);default:return x(t,new Error(`Unknown geometry format "${t}".`))}};if(n){const e=Ce(o?t[0]:t[0].map(((e,t)=>({raw:t.toString()}))),n,o?a:a.map((e=>""+(parseInt(e.match(/\d+/g)[0])-1))));if(o&&void 0===e)throw new Error(`Error parsing file data: Expected geometry columns ${geometryTypeHeaders[n][0].join(",")} are missing for GeometryType.${n}`);return y(e??[0],n)}const[p,d]=await Pe(t,l,o);if(p===GeometryFormat.NONE)return{columnIndices:[]};return d.length>1?u(d,p):f(d[0],pe.get(p))}(e),o=function(e,t){const{data:r,displayField:o,includeHeaderRow:n,inSpatialReference:a,outSpatialReference:i,generatePrimaryKey:s}=e,l={fields:[]},c=e=>!(!t.columnIndices||0===t.columnIndices.length)&&t.columnIndices.includes(e);let{primaryKeyField:m}=e,u=0;for(let t=0;t<r[0].length;t++){if(c(t))continue;const o=Ue(e,t,!s&&!m&&!l.fields.find((e=>"esriFieldTypeOID"===e.type)));let a=r[0][t]?.raw?.toString(),i=a?.replace(FIELD_NAME_REGEX,"_");n&&i||(i="field"+ ++u,a=F("gcx.api.data.convert.import-field-alias",u)),l.fields.push({alias:a,name:i,type:o}),"esriFieldTypeOID"===o&&(m=i)}if(l.spatialReference=i??t.geometries?.[0]?.spatialReference??a,t.geometries?.length){const e=t.geometries.filter((e=>void 0!==e)).map((e=>e.type)),r=e[0];l.geometryType=e.every((e=>e===r))?h(r):void 0}if(!l.fields.find((e=>"esriFieldTypeOID"===e.type))){const e=l.fields.length+1,t=!!l.fields.find((e=>"objectid"===e.name.toLowerCase()));m=t?`OBJECTID_${e}`:"OBJECTID",l.fields.push({name:m,alias:m,type:"esriFieldTypeOID"})}return l.displayField=o??l.fields.find((e=>!ee(e.name,m)&&"esriFieldTypeString"===e.type))?.name??l.fields.find((e=>!ee(e.name,m)))?.name??m,l.primaryKeyField=m,l}(e,t),n=await async function(e,t,r){const{data:o,includeHeaderRow:n,outFields:a,escapeFormulaChars:i,locale:s,numberFormat:l,dateFormat:c,timeFormat:m}=e,{spatialReference:u}=r,f=[],y=n?o.slice(1):o,p=(e,r)=>!t.columnIndices||0===t.columnIndices.length||!t.columnIndices.includes(r);return await Promise.all(y.map((async(e,o)=>{const n=new te;for(let t=0;t<r.fields.length;t++){const u=r.fields[t],f=e.filter(p);if(a.includes("*")||a.filter((e=>ee(e,u.name))).length>0){let e=await $e(f[t]?.raw,u,{escapeFormulaChars:i,dateFormat:c,numberFormat:l,timeFormat:m,locale:s});"esriFieldTypeOID"===u.type&&null===e&&(e=o),n.attributes.set(u.name,e)}}t.geometries&&(n.geometry=await Oe(t.geometries[o],u)),f.push(n)}))),f}(e,t,o);return new re({features:n,schema:o})}export async function toCsv(e,t){b("featureSet",e).isNotMissing();const r=Array.from(e),o={...{useFormattedValues:!1,alwaysQuote:!1,escapeFormulaChars:!0,delimiter:",",dateFormat:v.ROUND_TRIP,timeFormat:j.ROUND_TRIP,geometryFormat:r.some((e=>void 0!==e.geometry&&null!==e.geometry))?GeometryFormat.WKT:GeometryFormat.NONE,includeByteOrderMark:!0,outSpatialReference:a.WGS84,includeHeaderRow:!0,outFields:Te(e.source),rowDelimiter:navigator.platform?.startsWith("Win")?ie:"\n"},...t},{includeByteOrderMark:n,includeHeaderRow:i,delimiter:s,outFields:l,rowDelimiter:c}=o,m=[];n&&m.push("\ufeff");const u=Fe(r,o),f=Se(r,l,e.schema,!0),y=Se(r,l,e.schema,!1);if(i){const e=[];for(const t of u)e.push(De(t,o));for(const t of f)e.push(De(t,o));for(const t of y)e.push(De(t,o));const t=e.join(s)+c;m.push(t)}await Promise.all(r.map((async e=>{const t=[],r=(t,r)=>{const o=xe(e,t,r),n=e.schema.findFieldByName(t)?.type;return De(be(o,{...r,isDateOnly:"date-only"===n}),r)};t.push(...await async function(e,t){let r=await Ne(e,t);t.geometryFormat!==GeometryFormat.XYZ&&t.geometryFormat!==GeometryFormat.XY&&t.geometryFormat!==GeometryFormat.LAT_LON||(r=r.map((e=>void 0===e?"":be(e,t))));return r.map((e=>""===e?"":De(e,t)))}(e.geometry,o)),t.push(...f.map((e=>r(e,o)))),t.push(...y.map((e=>r(e,o))));const n=`${t.join(s)}${c}`;m.push(n)})));return new Blob(m,{type:"text/plain",endings:"\n"===c||c===ie?"transparent":"native"})}export async function csvToUploadData(e,t){let r;if(b("csvData",e).isNotMissing(),e instanceof Blob){const t=new Promise(((t,r)=>{const o=new FileReader;o.onload=()=>{t(o.result)},o.onerror=()=>{r(o.error)},o.readAsText(e)}));r=await t}else r=e;const o=ge(t),n=o.rowDelimiter||function(e){let t=se;return Ae(e,ie,((r,o)=>(0===r&&o===e.length||(t=ie),!1))),t}(r),a=o.delimiter??function(e,t,r){const o=",";if(0===e.length)return o;const n=[];if(Ae(e,t,((t,r)=>(r!==e.length||t!==r)&&(n.push(e.substring(t,r)),n.length<3))),0===n.length)return o;let a=[{delimiter:",",rowsDelimiterOccurrences:[],rowsNumberAdjacentOccurrences:[]},{delimiter:";",rowsDelimiterOccurrences:[]},{delimiter:"|",rowsDelimiterOccurrences:[]},{delimiter:"\t",rowsDelimiterOccurrences:[]},{delimiter:" ",rowsDelimiterOccurrences:[]}].filter((e=>n[0].includes(e.delimiter)));if(0===a.length)return o;for(const e of n)for(const t of a){let o=0,n=0;Ae(e,t.delimiter,((a,i)=>{if(i!==e.length&&o++,","===t.delimiter){const t=e.charAt(i-1),o=e.charAt(i+1);V(t,r)&&V(o,r)&&n++}return!0})),t.rowsDelimiterOccurrences.push(o),","===t.delimiter&&t.rowsNumberAdjacentOccurrences.push(n)}if(a=a.filter((e=>e.rowsDelimiterOccurrences.every((t=>e.rowsDelimiterOccurrences[0]===t)))).sort(((e,t)=>t.rowsDelimiterOccurrences[0]-e.rowsDelimiterOccurrences[0])),a.length>1&&","===a[0].delimiter&&null!=r&&r!==S){const e=a[0];if(null!=e&&","===e.delimiter&&","===Intl.NumberFormat(r).formatToParts(1.1).find((e=>"decimal"===e.type))?.value)for(let t=0;t<e.rowsDelimiterOccurrences.length;t++)if(e.rowsDelimiterOccurrences[t]<=e.rowsNumberAdjacentOccurrences[t]){a=a.filter((e=>","!==e.delimiter));break}}if(0===a.length)return o;return a[0].delimiter}(r,n,t.locale),i=function(e,t,r){const o=[],n=(e,t)=>{const o=[];return Ae(e,r,((r,n)=>{const a=e.substring(r,n);return o.push({raw:Re(a,t,o.length)}),!0})),o};if(Ae(e,t,((t,r)=>{const a=e.substring(t,r);return a.length>0&&o.push(n(a,o.length)),!0})),o.length){const e=o[0].length;o.forEach(((t,r)=>{if(t.length!==e)throw new Error(`Detected invalid CSV: Row ${r} does not have expected number of columns: ${e}`)}))}return o}(r,n,a);let{geometryFormat:s,geometryFields:l}=t;if(!s){const[e,t]=await Pe(i,o.inSpatialReference,o.includeHeaderRow);s=e,l=t.map((e=>o.includeHeaderRow?i[0][e]?.raw??F("gcx.api.data.convert.import-field-alias",(e+1).toString()):F("gcx.api.data.convert.import-field-alias",(e+1).toString())))}return{data:i,...o,geometryFormat:s,geometryFields:l}}export async function csvToFeatureSet(e,t){const r=ge(t);return uploadDataToFeatureSet(await csvToUploadData(e,r))}export async function toXLSX(e,t){b("featureSet",e).isNotMissing();const r=Array.from(e),o={...{useFormattedValues:!1,includeHeaderRow:!0,escapeFormulaChars:!0,geometryFormat:r.some((e=>void 0!==e.geometry&&null!==e.geometry))?GeometryFormat.WKT:GeometryFormat.NONE,outFields:Te(e.source),outSpatialReference:a.WGS84,dateFormat:v.DEFAULT,timeFormat:j.DEFAULT,numberFormat:P.DEFAULT,sheetName:"sheet1"},...t},{outFields:n,includeHeaderRow:i,dateFormat:s,timeFormat:l,numberFormat:c}=o,m=Fe(r,o),u=Se(r,n,e.schema,!0),f=Se(r,n,e.schema,!1),y=await import("xlsx"),p=y.utils.sheet_new();let d=!1;if(i){const t=m.concat(u).concat(function(e,t){const r=t?.schema?.fieldExtensions.initializedItems.map((e=>e.field));return e.map((e=>r?.find((t=>ee(t.name,e)))?.alias??e))}(f,e.source));d=!0,y.utils.sheet_add_aoa(p,[t],{cellDates:!0})}await Promise.all(r.map((async e=>{const t=[],r=new Set,n=new Set;t.push(...await Ne(e.geometry,o));for(const r of u){const n=ke(e.attributes.get(r),o);t.push(n)}for(const a of f){const i=xe(e,a,o);if(i instanceof D){const o=e.schema.findFieldByName(a);"time-only"===o?.type&&r.add(t.length)}else if(i instanceof Date){const r=e.schema.findFieldByName(a);"date-only"===r?.type&&n.add(t.length)}const s=ke(i,o);t.push(s)}if(!t.every((e=>"string"!=typeof e||e.length<=32767)))return void fe().warn(`toXLSX cell limit exceeded, feature (${e.primaryKey??e.id}) omitted.`);y.utils.sheet_add_aoa(p,[t],{cellDates:!0,origin:d?-1:void 0}),d=!0;const a=y.utils.decode_range(p["!ref"]);for(let e=a.s.c;e<=a.e.c;e++){const t=p[y.utils.encode_cell({r:a.e.r,c:e})];"d"===t.t?r.has(e)?t.z=Je(l??j.ROUND_TRIP):n.has(e)?t.z=Be(s??v.ROUND_TRIP):t.z=He(s??v.ROUND_TRIP):"n"===t.t&&(t.z=ze(c))}})));const g={SheetNames:[],Sheets:{}};g.SheetNames.push(o.sheetName),g.Sheets[o.sheetName]=p;const w=y.write(g,{type:"binary",bookType:"xlsx",compression:!0,bookSST:!0,cellDates:!0}),h=new Uint8Array(w.length);for(let e=0;e<w.length;e++)h[e]=w.charCodeAt(e);return new Blob([h.buffer],{type:"text/plain"})}export async function xlsxToUploadData(e,t){b("xlsxData",e).isNotMissing();const r=we(t),o=await async function(e,t){const r=await import("xlsx"),o=new Promise(((o,n)=>{const a=new FileReader;a.onload=()=>{const e=new Uint8Array(a.result);let n="";for(const t of e)n+=String.fromCharCode(t);const i=r.read(n,{type:"binary",cellDates:!0}),s=t.sheetName||i.SheetNames[0],l=i.Sheets[s];o(l)},a.onerror=()=>{n(a.error)},a.readAsArrayBuffer(e)})),n=await o,a=r.utils.decode_range(n["!ref"]),i=[];for(let e=a.s.r;e<=a.e.r;e++){const t=[];for(let o=a.s.c;o<=a.e.c;o++){const a=n[`${r.utils.encode_cell({r:e,c:o})}`];a&&"d"===a.t&&a.v instanceof Date&&(a.v=new Date(a.v.getTime()+6e4*a.v.getTimezoneOffset())),t.push(a?{raw:a.v,formatted:"s"===a.t?void 0:a.w}:{raw:""})}i.push(t)}return i}(e,r);let{geometryFormat:n,geometryFields:a}=t;if(!n){const[e,t]=await Pe(o,r.inSpatialReference,r.includeHeaderRow);n=e,a=t.map((e=>r.includeHeaderRow?o[0][e]?.raw.toString()??F("gcx.api.data.convert.import-field-alias",(e+1).toString()):F("gcx.api.data.convert.import-field-alias",(e+1).toString())))}return{data:o,...r,geometryFormat:n,geometryFields:a}}export async function xlsxToFeatureSet(e,t){b("xlsxData",e).isNotMissing();const r=we(t);return uploadDataToFeatureSet(await xlsxToUploadData(e,r))}export function kmlHexToEsriColor(t){return e.fromHex(`#${t.match(/.{2}/g).reverse().join("")}`)}export function parseKMLCoordinates(e){return e.trim().split(/\s+/).map((e=>{const[t,r,o]=e.split(",").map(Number);return{x:t,y:r,z:o}}))}export function parseKMLSymbol(t,r,o){if(t){const r=t.querySelector("IconStyle > Icon > href")?.textContent;if(r)return new y({url:r,width:32,height:32});const o=t.querySelector("PolyStyle");if(o){const t=o.querySelector("color")?.textContent,r=t?kmlHexToEsriColor(t):new e([0,0,0,1]);return new p({color:r,outline:{color:[0,0,0,.5],width:1}})}const n=t.querySelector("LineStyle");if(n){const t=n.querySelector("color")?.textContent,r=t?kmlHexToEsriColor(t):new e([0,0,0,1]),o=parseFloat(n.querySelector("width")?.textContent||"1");return new d({color:r,width:o})}}return getDefaultSymbol(o,"polygon"===r?"polygon":"point"===r?"point":"polyline")}export async function toShapefile(e,t){b("featureSet",e).isNotMissing();const[{default:r},o]=await Promise.all([import("jszip"),import("../forked-libs/shp-write/index.js")]),n=Array.from(e),i={...{useFormattedValues:!1,outFields:Te(e.source),fileName:e.title||"export"},...t},{outFields:s,outSpatialReference:l,fileName:c}=i,m=e=>e.geometry.hasZ||e.geometry.hasM,u=new Map,f=n.filter((e=>M(e.geometry)));u.set("POINTZ",f.filter(m)),u.set("POINT",f.filter((e=>!m(e))));const y=n.filter((e=>E(e.geometry)));u.set("MULTIPOINTZ",y.filter(m)),u.set("MULTIPOINT",y.filter((e=>!m(e))));const p=n.filter((e=>R(e.geometry)));u.set("POLYLINEZ",p.filter(m)),u.set("POLYLINE",p.filter((e=>!m(e))));const d=n.filter((e=>A(e.geometry)||I(e.geometry)));u.set("POLYGONZ",d.filter(m)),u.set("POLYGON",d.filter((e=>!m(e))));const g=Se(n,s,e.schema,!0);let w=Se(n,s,e.schema,!1);w=g.concat(w);const h=new r,F=Array.from(u.keys()).filter((e=>u.get(e).length>0));await Promise.all(F.map((async t=>{const r=u.get(t),n=await Promise.all(r.map((e=>Oe(e.geometry,l)))),s=await async function(e){const{wkid:t,wkt:r}=e[0].spatialReference;if(!e.every((e=>e.spatialReference.wkid===t&&e.spatialReference.wkt===r)))throw new Error("Cannot create shapefile that contains geometries with different spatial references.");return r??await X(t??a.WGS84.wkid)}(n),m=i.useFormattedValues?Object.assign({},...w.map((e=>({[e]:ue.STRING})))):function(e,t,r,o){const n={};for(const a of t){if(e.some((e=>Me(e,a)))){n[a]=ue.STRING;continue}const t=r?r.fields.find((e=>ee(e.name,a))):void 0;if(t){switch(t.type){case"oid":case"double":case"integer":case"single":case"small-integer":case"big-integer":n[a]=ue.NUMBER;break;case"date":case"timestamp-offset":n[a]=o?ue.NUMBER:ue.DATE;break;default:n[a]=ue.STRING}continue}const i=(e,t)=>e.attributes.get(t)??e.presentableAttributes.get(t);e.every((e=>i(e,a)instanceof Date||void 0===i(e,a)))&&e.some((e=>i(e,a)instanceof Date))?n[a]=o?ue.NUMBER:ue.DATE:e.every((e=>"number"==typeof i(e,a)||void 0===i(e,a)))&&e.some((e=>"number"==typeof i(e,a)))?n[a]=ue.NUMBER:e.every((e=>"boolean"==typeof i(e,a)||void 0===i(e,a)))&&e.some((e=>"boolean"==typeof i(e,a)))?n[a]=ue.BOOLEAN:n[a]=ue.STRING}return n}(r,w,e.schema,"timestamp"===i.dateFormat),f=function(e){return e.map((e=>{if(M(e)){const{x:t,y:r,z:o,m:n}=e,a=[t,r];return e.hasZ&&a.push(o),e.hasM&&a.push(n),We(a,e)}if(E(e))return Xe(e.points,e);if(R(e))return qe(e.paths,e);if(A(e))return qe(e.rings,e);if(I(e)){const t=[e.xmin,e.ymax];return[[t,[e.xmax,e.ymax],[e.xmax,e.ymin],[e.xmin,e.ymin],t]]}throw new Error("Unsupported geometry type.")}))}(n),y=function(e,t,r,o){const n=[];for(const a of e){const e={};for(const n of t){let t=xe(a,n,o);if(null==t&&(t=""),o.useFormattedValues)t=t.toString();else{t=Ye(t,r[n],{...o,isDateOnly:"date-only"===a.schema.findFieldByName(n)?.type})}e[n.replaceAll(".","_")]=t}n.push(e)}return n}(r,w,m,i);o.write(y,t,f,((e,r)=>{const o=F.length>1?`${c}_${t.toLowerCase()}`:c;h.file(`${o}.shp`,r.shp.buffer,{binary:!0}),h.file(`${o}.shx`,r.shx.buffer,{binary:!0}),h.file(`${o}.dbf`,r.dbf.buffer,{binary:!0}),h.file(`${o}.prj`,s)}))})));const S=await h.generateAsync({type:"uint8array"});return new Blob([S.buffer],{type:"text/plain"})}export async function kmlToLayerExtensions(e){b("blob",e).isNotMissing();const a=await e.text(),c=(new DOMParser).parseFromString(a,"application/xml"),m=function(e,a,u=!1){const f={};c.querySelectorAll("Style").forEach((e=>{f[`#${e.id}`]=e}));const y=e.querySelector(":scope > name")?.textContent??"Unnamed Container",p=new Map;e.querySelectorAll(":scope > Placemark").forEach(((e,i)=>{const s=e.querySelector("name")?.textContent??"",l=e.querySelector("description")?.textContent??"",c=function(e){const t=e.querySelector("Point > coordinates"),a=e.querySelector("LineString > coordinates"),i=e.querySelector("Polygon");if(t?.textContent){const[e]=parseKMLCoordinates(t.textContent.replace(/ /g,""));return new r(e)}if(a?.textContent)return new n({paths:[parseKMLCoordinates(a.textContent).map((({x:e,y:t})=>[e,t]))]});if(i?.textContent){const e=i.querySelector("outerBoundaryIs > LinearRing > coordinates");if(e?.textContent){const t=[parseKMLCoordinates(e.textContent).map((({x:e,y:t})=>[e,t]))];return new o({rings:t})}}return}(e);if(c?.type){const r=e.querySelector("styleUrl")?.textContent,o=parseKMLSymbol(r?f[r]:e.querySelector("Style"),c.type,a);p.has(c.type)||p.set(c.type,{graphics:[],symbols:[]});let n=function(e,t){for(let r=0;r<e.length;r++)if(Ze(e[r],t))return r;return-1}(p.get(c.type).symbols,o);-1===n&&(p.get(c.type).symbols.push(o),n=p.get(c.type).symbols.length-1),p.get(c.type).graphics.push(new t({geometry:c,attributes:{name:s,description:l,SymbolID:n,OBJECTID:y+i}}))}}));const d=e.querySelectorAll(":scope > Folder, :scope > Document");if(u||1!==p.size||0!==d.length){const e=new N({layer:new s({title:y})});return p.forEach(((t,r)=>{const o=new i({displayField:"name",title:`${r.slice(0,1).toUpperCase()+r.slice(1)}s`,source:t.graphics,renderer:Ke(t.symbols),fields:[new l({name:"OBJECTID",type:"oid",alias:"OBJECTID"}),new l({name:"SymbolID",type:"integer",alias:"SymbolID",editable:!1}),new l({name:"name",type:"string",alias:"name"}),new l({name:"description",type:"string",alias:"description",defaultValue:""})]}),n=new T({layer:o});e.layerExtensions.add(n)})),d.forEach(((t,r)=>{const o=m(t,r);e.layerExtensions.add(o)})),e}{const e=[...p.values()][0],t=new i({displayField:"name",title:y,source:e.graphics,renderer:Ke(e.symbols),fields:[new l({name:"OBJECTID",type:"oid",alias:"OBJECTID"}),new l({name:"SymbolID",type:"integer",alias:"SymbolID",editable:!1}),new l({name:"name",type:"string",alias:"name"}),new l({name:"description",type:"string",alias:"description",defaultValue:""})]});return new T({layer:t})}},u=[];return c.querySelectorAll("kml > Document, kml > Folder").forEach(((e,t)=>{const r=m(e,t,!0);r.layerExtensions.length&&u.push(r)})),u}export async function dxfToLayerExtensions(e,t,r){const{inputSpatialReference:o,outputSpatialReference:n}=t;b("options.dxfBlob",e).isNotMissing(),b("options.inputSpatialReference",o).isNotMissing(),b("options.outputSpatialReference",n).isNotMissing();const a=new oe(o,n,r),i=a.getContext(),l=await e.text(),c=new w;await Q();try{const e=c.parseSync(l);if(!e)throw new Error("DXF parsing failed: parser returned null");i.dxf=e}catch(e){throw e instanceof Error?e:new Error(String(e))}const m=e instanceof File?e.name:"dxf-layer",u=m.replace(/[^a-zA-Z0-9_.-]/g,"_");if(i.fileName=m,i.sanitizedFileName=u,i.subLayers=await a.processAll(),!i.subLayers||0===i.subLayers.length)return[];const f=new s({id:`dxf-group-${u}-${(new Date).getTime()}`,title:m,visible:!0}),y={layer:f,visibilityMode:"independent"};return f.layers.addMany(i.subLayers),[new N(y)]}export async function shapefileToUploadData(e,t){b("shapefileData",e).isNotMissing();const o=he(t),n=new Promise(((t,r)=>{const o=new FileReader;o.onload=()=>{t(o.result)},o.onerror=()=>{r(o.error)},o.readAsArrayBuffer(e)})),[{default:i},{default:s}]=await Promise.all([import("jszip"),import("shpjs")]),l=await n,c=await i.loadAsync(new Uint8Array(l)),m=new O;c.forEach(((e,t)=>{t&&m.set(t.name,t)}));const u=c.filter((()=>!0)).map((e=>e.name));let f,y=u.filter((e=>e.endsWith(".shp"))).map((e=>e.substring(0,e.length-4)));if(y=function(e){if(!e.length)return[];let t=e[0];const r=t.match(me);return r?(t=r[1],e.filter((e=>{const r=e.match(me);return r&&r[1]===t}))):[t]}(y),u.some((e=>e.endsWith(".prj")))&&!y.every((e=>m.has(`${e}.prj`))))throw new Error("Shapefile zip must contain the same prj file for each separate shapefile");await Promise.all(u.filter((e=>e.endsWith(".prj"))).map((async e=>{const t=await c.file(e).async("string");if(f){if(t!==f)throw new Error("Shapefile zip must contain the same prj file for each separate shapefile")}else f=t})));let p=[],d=[];for(const e of y){if(!m.has(`${e}.shp`)||!m.has(`${e}.shx`)||!m.has(`${e}.dbf`))throw new Error("Shapefile must contain shp, shx, and dbf files.");const t=s.parseShp(await m.get(`${e}.shp`).async("uint8array")),r=s.parseDbf(await m.get(`${e}.dbf`).async("uint8array"));if(r.length!==t.length)throw new Error("Shapefile must contain shp, shx, and dbf files.");p=p.concat(r),d=d.concat(t)}const g=await Promise.all(d.map((e=>async function(e,t){const o=M(e)?function(e){b("geometry.coordinates",e.type).matches("Point"),b("geometry.coordinates",e.coordinates).satisfies((e=>"number"==typeof e||Array.isArray(e)));const[t,o,n]=e.coordinates,i=new r({x:t,y:o,spatialReference:a.WGS84});if(Array.isArray(n)){const[e,t]=n;!e&&!t||e?i.z=e:i.m=t}return i}(e):await Z(e);if(t){let e;try{const r=await q(t);e=new a({wkid:U(r)})}catch{}e||(e=new a({wkt:t})),o.spatialReference=e}return o}(e,f)))),w=geometryTypeHeaders[GeometryFormat.ARCGIS_JSON][0][0];p.forEach(((e,t)=>e[w]=JSON.stringify(g[t].toJSON())));return{data:function(e){const t=e.map((e=>Object.keys(e))).reduce(((e,t)=>e.concat(t.filter((t=>!e.includes(t))))),[]);return[t.map((e=>({raw:e}))),...e.map((e=>t.map((t=>({raw:e[t]})))))]}(p),...o,includeHeaderRow:!0,geometryFormat:GeometryFormat.ARCGIS_JSON,geometryFields:[w],inSpatialReference:g[0]?.spatialReference??a.fromJSON({wkid:4326})}}export async function shapefileToFeatureSet(e,t){b("shapefileData",e).isNotMissing();const r=he(t);return uploadDataToFeatureSet(await shapefileToUploadData(e,r))}export function getDefaultSymbol(e,t){const r=e%8;let o=["#FFDBFF","#88D6FF","#7F9FC3","#FF8200","#F34A53","#76E3B9","#E7BFFF","#FFC467"][r],n=["#EF3786","#005A99","#2D5070","#790C00","#4C0000","#006543","#6244A9","#904200"][r];if(Math.floor(e/8)%2!=0){const e=o;o=n,n=e}switch(t){case"point":case"multipoint":return new g({color:o,outline:{color:n}});case"polyline":return new d({color:o,width:"2"});case"polygon":return new p({color:o,outline:{color:n}});case"mesh":return new f({symbolLayers:[{type:"fill",material:{color:o},outline:{color:n}}]})}}function de(e){return{escapeFormulaChars:!0,outFields:["*"],generatePrimaryKey:!1,locale:S,detectOid:!e?.primaryKeyField}}function ge(e){return{...{includeHeaderRow:!0,inSpatialReference:a.WGS84,...de(e)},...e}}function we(e){return{...{includeHeaderRow:!0,inSpatialReference:a.WGS84,...de(e)},...e}}function he(e){return{...{...de(e)},...e}}function Fe(e,t){return t.geometryFormat===GeometryFormat.XYZ?["x","y","z"]:t.geometryFormat===GeometryFormat.XY?["x","y"]:t.geometryFormat===GeometryFormat.LAT_LON?["latitude","longitude"]:t.geometryFormat===GeometryFormat.NONE?[]:["geometry"]}function Se(e,t,r,o){const n=r.fields.filter((e=>"oid"===e.type)).map((e=>e.name)).toArray();if(o)return n;if(t&&!t.includes("*"))return t.filter((e=>!n.includes(e)));{const t=r.fields.filter((e=>"oid"!==e.type)).map((e=>e.name)).toArray();let o=[];for(const r of e)for(const e of r.attributes.keys())t.includes(e)||n.includes(e)||o.includes(e)||o.push(e);return o=o.sort(),t.concat(o)}}function Te(e){if(!e)return["*"];const t=e.featureSettings.popupTemplate?.content;return(Array.isArray(t)?t.find((e=>"fields"===e.type))?.fieldInfos?.filter((e=>e.visible))?.map((e=>e.fieldName)):void 0)??e.featureSettings.popupTemplate?.fieldInfos?.filter((e=>e.visible))?.map((e=>e.fieldName))??["*"]}async function Ne(e,t){const r=await Oe(e,t.outSpatialReference);if(t.geometryFormat===GeometryFormat.XYZ){if(!r)return["","",""];if(!M(r))throw new Error("Cannot use geometry format XYZ with non-point geometry");return[r.x,r.y,r.z]}if(t.geometryFormat===GeometryFormat.XY){if(!r)return["",""];if(!M(r))throw new Error("Cannot use geometry format XY with non-point geometry");return[r.x,r.y]}if(t.geometryFormat===GeometryFormat.LAT_LON){if(!r)return["",""];if(!M(r))throw new Error("Cannot use geometry format LAT_LONG with non-point geometry");return[r.y,r.x]}return t.geometryFormat===GeometryFormat.ARCGIS_JSON?r?[JSON.stringify(r.toJSON())]:[""]:t.geometryFormat===GeometryFormat.WKT?r?[await k(r)]:[""]:t.geometryFormat===GeometryFormat.GEO_JSON?r?[JSON.stringify(await Y(r))]:[""]:[]}async function Oe(e,t){return e?.spatialReference&&!e.spatialReference.equals(t)&&t?(await z([e],t))[0]:e}function De(e,t){const r=[t.delimiter,ae,"\r","\n",t.rowDelimiter];if(t.alwaysQuote||r.some((t=>e.includes(t)))){const t=e.replace(new RegExp(ae,"g"),`${ae}${ae}`);return`${ae}${t}${ae}`}return e}function be(e,t){if(null==e)return"";if(!t.useFormattedValues){if("number"==typeof e){const r=t.numberFormat||P.ROUND_TRIP;return $(r,e)}if(e instanceof Date)return"timestamp"===t.dateFormat?e.getTime().toString():_({format:t.dateFormat,timeZone:"UTC",isDateOnly:t.isDateOnly},e);if(e instanceof D)return B({format:t.timeFormat},e)}let r=e.toString();return t.escapeFormulaChars&&(r=Ee(r)),r}function xe(e,t,r){if(r.useFormattedValues||Me(e,t))return e.presentableAttributes.get(t)??e.attributes.get(t);const o=e.schema.findFieldByName(t)?.type;if(null!=o)switch(o){case"date":case"date-only":case"timestamp-offset":{const r=G(e.attributes.get(t));if(!isNaN(r.getTime()))return r;break}case"time-only":{const r=H(e.attributes.get(t));if(r.isValid)return r;break}}return e.attributes.get(t)??e.presentableAttributes.get(t)}function Me(e,t){return!!ee(t,e.schema.typeIdField)||("coded-value"===e.type?.domains?.[t]?.type||"coded-value"===e.schema.findFieldByName(t)?.domain?.type)}function Ee(e){for(const t of ne)if(e.startsWith(t))return`\t${e}`;return e}function Re(e,t,r){const o=e.startsWith(ae),n=e.endsWith(ae);if(o&&!n||!o&&n)throw new Error(`Detected invalid CSV: Missing opening or closing quote for value at row:${t} column:${r}`);const a=o?e.substring(1,e.length-1):e;let i=-1;return Ae(a,ae,((e,o)=>{if(o===a.length)return!0;if(i<0){if(o!==a.length)return i=o,!0}else if(o===i+1)return i=-1,!0;throw new Error(`Detected invalid CSV: Non-escaped quote for value at row:${t} column:${r}`)})),a.replace(new RegExp(`${ae}${ae}`,"g"),ae)}function Ae(e,t,r){let o,n=!1,a=0,i=0;for(;o=e.indexOf(t,a),!(o<0);){for(let t=a;t<o;)e.substring(t).startsWith(ae)?(n=!n,t+=1):t++;const s=o+t.length;if(!n){const e=r(i,o);if(i=s,!e)return}a=s}r(i,e.length)}async function Ie(e,t){const r=JSON.parse(e),o=(await import("@arcgis/core/geometry/support/jsonUtils")).fromJSON(r);return r.spatialReference||(o.spatialReference=t),o}async function Ge(e,t){const r=await Z(JSON.parse(e));return r.spatialReference=t,r}async function _e(e,t){const r=await W(e);return r.spatialReference=t,r}function Ce(e,t,r){const o=r?[r]:geometryTypeHeaders[t];for(const t of o){const r=t.map((t=>e.map((e=>e?.raw?.toString().trim().toLowerCase())).indexOf(t.trim().toLowerCase())));if(r.every((e=>e>=0)))return r}}async function Le(e,t){return(await Promise.all(e.map((async(e,r)=>{const o=e?.raw;if("string"==typeof o&&""!==o)try{return await t(o,void 0),r}catch{return}})))).find((e=>void 0!==e))}function ve(e,t,r){return"inv"===t?"string"==typeof e?parseFloat(e.replaceAll(",","")):e:U({locale:t,format:r},e)}async function Pe(e,t,r){const o=r?e.slice(1):e;if(r){const r=Ce(e[0],GeometryFormat.ARCGIS_JSON);if(void 0!==r)for(const[e,n]of ye){try{await je(r[0],n,t,o)}catch{continue}return[e,[r[0]]]}const n=[GeometryFormat.XYZ,GeometryFormat.XY,GeometryFormat.LAT_LON];for(const t of n){const r=Ce(e[0],t);if(void 0!==r)return[t,r]}}for(const[e,r]of ye){const n=await Le(o[0],r);if(void 0!==n){try{await je(n,r,t,o)}catch{continue}return[e,[n]]}}return[GeometryFormat.NONE,[]]}async function je(e,t,r,o){return{columnIndices:[e],geometries:await Promise.all(o.map((t=>t[e])).map((e=>{if(e?.raw)return t(e.raw.toString(),r)})))}}function Ue(e,t,r){let o=!1,n=!0,a=!0,i=!0,s=!0,l=!0;const c=new Set,{data:m,includeHeaderRow:u,dateFormat:f,timeFormat:y,primaryKeyField:p,locale:d}=e,g=u?m[0]:[],w=u?m.slice(1):m;for(const e of w){const r=e[t];r?.raw&&(c.add(r.raw),o=!0,n&&(n=V(r.raw,d)||Number.isNaN(r.raw)),a&&(a=r.raw instanceof Date||G(f||C,r.raw)!==L),s&&(s=G(f||le,r.formatted)!==L),i&&(i=r.raw instanceof D||H(y||J,r.raw).isValid),l&&(l=H({format:y||ce,locale:"en"},r.formatted).isValid))}const h=c.size===w.length;return p&&g[t]?.raw===p||r&&o&&h&&n?"esriFieldTypeOID":o&&l?"esriFieldTypeTimeOnly":o&&s?"esriFieldTypeDate":o&&n?"esriFieldTypeDouble":o&&i?"esriFieldTypeTimeOnly":o&&a?"esriFieldTypeDate":"esriFieldTypeString"}async function $e(e,t,r){const{escapeFormulaChars:o,locale:n,numberFormat:a,dateFormat:i,timeFormat:s}=r;if("esriFieldTypeDouble"===t.type||"esriFieldTypeOID"===t.type)return"number"==typeof e?e:e?ve(e,n,a):null;if("esriFieldTypeDate"===t.type){if(e instanceof Date)return e.getTime();if("number"==typeof e){const t=(await import("xlsx")).SSF.parse_date_code(e);return t?new Date(t.y,t.m-1,t.d,t.H,t.M,t.S).getTime():void 0}return""===e?null:G({locale:n,format:i},e).getTime()}if("esriFieldTypeTimeOnly"===t.type){if(e instanceof D)return e.toString();if(e instanceof Date)return new D(e).toString();if("number"==typeof e){const t=(await import("xlsx")).SSF.parse_date_code(e);return t?new D(`${t.H.toString().padStart(2,"0")}:${t.M.toString().padStart(2,"0")}:${t.S.toString().padStart(2,"0")}`).toString():void 0}return""===e?null:H({locale:n,format:s},e).toString()}const l=e?.toString()??"";if(o&&l.startsWith("\t"))for(const e of ne)if(l.length>1&&l.charAt(1)===e)return l.substring(1);return l}function He(e){switch(e){case v.DATE_SHORT:return"dd/MM/yyyy";case v.DATE_LONG:return"MMMM d, yyyy";case v.TIME_SHORT:return"h:mm AM/PM";case v.TIME_LONG:return"h:mm:ss AM/PM";case v.DATE_TIME_SHORT:case v.DEFAULT:return"MMM d yyyy h:mm AM/PM";case v.DATE_TIME_LONG:return"MMMM d yyyy h:mm AM/PM";case v.FULL:return"dddd, MMMM d yyyy h:mm AM/PM";case v.ISO_8601:case v.ROUND_TRIP:return'yyyy-MM-dd"T"HH:mm:ss';default:{const t=e.replace(/tt/g,"AM/PM");return t.includes("z")&&fe().warn("Warning: Excel will not recognize timezone format 'z', 'zz', or 'zzz'"),t.includes("h")&&!t.includes("AM/PM")&&fe().warn("Warning: Excel will interpret 'h' as 'H' if the format does not have an AM/PM designator"),t}}}function Be(e){switch(e){case v.DATE_SHORT:return"dd/MM/yyyy";case v.DATE_LONG:return"MMMM d, yyyy";case v.DATE_TIME_SHORT:case v.DEFAULT:return"MMM d yyyy";case v.DATE_TIME_LONG:return"MMMM d yyyy";case v.FULL:return"dddd, MMMM d yyyy";case v.ISO_8601:case v.ROUND_TRIP:return"yyyy-MM-dd";default:return e.replace(/TtZzHhmSsUua/g,"")}}function Je(e){switch(e){case j.TIME_SHORT:return"h:mm AM/PM";case j.TIME_LONG:return"h:mm:ss AM/PM";case j.ISO_8601:case j.ROUND_TRIP:return"HH:mm:ss";default:{const t=e.replace(/tt/g,"AM/PM");return t.includes("h")&&!t.includes("AM/PM")&&fe().warn("Warning: Excel will interpret 'h' as 'H' if the format does not have an AM/PM designator"),t}}}function ze(e){switch(e){case P.ACCOUNTING:return'_("$"* #,##0.00_);_("$"* (#,##0.00);_("$"* "-"??_);_(@_)';case P.CURRENCY:return'"$"#,##0.00';case P.FIXED_POINT:case P.DEFAULT:return"0.0000";case P.NUMBER:return"#,##0.0000";case P.PERCENT:return"0%";case P.ROUND_TRIP:return"0.00000";default:return e}}function ke(e,t){if(null==e)return"";if(!t.useFormattedValues){if("number"==typeof e)return e;if(e instanceof Date)return"timestamp"===t.dateFormat?e.getTime():e;if(e instanceof D)return e.toDate()}let r=e.toString();return t.escapeFormulaChars&&(r=Ee(r)),r}function We(e,t){return 3===e.length&&!t.hasZ&&t.hasM?[e[0],e[1],void 0,e[2]]:e}function Xe(e,t){return e.map((e=>We(e,t)))}function qe(e,t){return e.map((e=>Xe(e,t)))}function Ye(e,t,r){switch(t){case ue.NUMBER:return e instanceof Date?e.getTime():U(e);case ue.STRING:return e instanceof Date?_({format:r.dateFormat??v.ROUND_TRIP,timeZone:"UTC",isDateOnly:r.isDateOnly},e):e instanceof D?B({format:r.timeFormat??j.ROUND_TRIP},e):"number"==typeof e?$(r.numberFormat??P.DEFAULT,e):e.toString();case ue.BOOLEAN:return!!e;case ue.DATE:return G(e);default:return e.toString()}}function Ze(e,t){return JSON.stringify(e.toJSON())===JSON.stringify(t.toJSON())}function Ke(e){return 1===e.length?new c({symbol:e[0]}):new m({field:"SymbolID",uniqueValueInfos:[...e.map(((e,t)=>new u({label:t.toString(),symbol:e,value:t})))]})}
@@ -1,6 +1,6 @@
1
1
  import Graphic from "@arcgis/core/Graphic";
2
2
  import Point from "@arcgis/core/geometry/Point";
3
- import type SpatialReference from "@arcgis/core/geometry/SpatialReference";
3
+ import SpatialReference from "@arcgis/core/geometry/SpatialReference";
4
4
  import type FeatureLayer from "@arcgis/core/layers/FeatureLayer.js";
5
5
  import GeoJSONLayer from "@arcgis/core/layers/GeoJSONLayer";
6
6
  import GraphicsLayer from "@arcgis/core/layers/GraphicsLayer";
@@ -1 +1 @@
1
- import e from"@arcgis/core/Color";import t from"@arcgis/core/Graphic";import o from"@arcgis/core/geometry/Point";import n from"@arcgis/core/layers/GeoJSONLayer";import r from"@arcgis/core/layers/GraphicsLayer";import s from"@arcgis/core/symbols/SimpleFillSymbol";import i from"@arcgis/core/symbols/SimpleLineSymbol";import a from"@arcgis/core/symbols/TextSymbol.js";import{project as l}from"../../utilities/geometry.js";import{delay as c}from"../../utilities/promise.js";import{getDefaultSymbol as x}from"../convert.js";import{normalizeFillStyle as d,normalizeLineOutline as y,intToRGB as p,deriveAnnotationMinScale as f,sanitizeSymbolWidth as h}from"./_dxfFunctions.js";export class DxfToGeoJsonLineMapper{dxfContext;constructor(e){this.dxfContext=e,this.dxfContext.lastLineEnd=void 0,this.dxfContext.lastLineLayer=void 0}async processLine(e){const{vertices:t}=e;if(!t||t.length<2)return;const o=t[0],n=t[1];if(!o||!n)return;const[r,s]=await Promise.all([this.dxfContext.convertToSpatialReference(o.x,o.y),this.dxfContext.convertToSpatialReference(n.x,n.y)]),i=e.layer||"default",a={type:"Feature",geometry:{type:"LineString",coordinates:[r,s]},properties:{...e}};if(this.dxfContext.lastLineEnd&&this.dxfContext.lastLineLayer===i&&this._isSamePoint(this.dxfContext.lastLineEnd,r)){const e=this.dxfContext.lineFeatures.at(-1);if("LineString"===e?.geometry?.type){e.geometry.coordinates.push(s)}else this.dxfContext.lineFeatures.push(a)}else this.dxfContext.lineFeatures.push(a);this.dxfContext.lastLineEnd=s,this.dxfContext.lastLineLayer=i;const l=this.dxfContext.dxf.tables?.layer?.layers?.[i],c=e.color??l?.color??x(this.dxfContext.colorIndex++,"polyline").color,d=this._getLayerColor(e,c),y=`${e.layer}-${e.type}-${e.handle}`;this.dxfContext.renderer_Object_Line[y]={value:e.layer||"default",symbol:{type:"simple-line",color:d,width:e.lineweight||1.5,style:(()=>{const t=e.lineType&&this.dxfContext.dxf.tables?.lineType?.lineTypes?.[e.lineType];return"object"==typeof t&&t?.pattern?{pattern:t.pattern.map((e=>parseFloat(e)))}:"solid"})()}}}async processPolyline(t){const o=await this._getPolylineCoordinates(t),n=!!t.closed;n&&o.length>0&&this._ensureClosed(o);const r=this.dxfContext.dxf.tables?.layer?.layers?.[t.layer];let s;s=t.color,void 0!==s&&0!==s&&256!==s||(s=r?.color),void 0===s&&(s=x(this.dxfContext.colorIndex++,"polyline")?.color??new e("black"));const i="number"==typeof s?this.dxfContext.intToRGB(s):s,a=this._buildPolylineFeature(t,o,n,s);if(n)if(Array.isArray(i))this._applyPolygonRenderer(t,i,a);else if(i&&"object"==typeof i&&"r"in i){const e=[i.r,i.g,i.b,1];this._applyPolygonRenderer(t,e,a)}else{const o=x(this.dxfContext.colorIndex++,"polygon").color,n=o instanceof e?o.toRgba():o;this._applyPolygonRenderer(t,n,a)}else this._applyLineRenderer(t,a)}async processLWPolyline(e){const t=this._buildBulgeInterpolatedPoints(e),n=await this.dxfContext.projectMany(t.map((e=>new o({x:e.x,y:e.y,spatialReference:this.dxfContext.sourceSR})))),r=n[0],s=n[n.length-1],i=!!r&&!!s&&Math.abs(r[0]-s[0])<1e-6&&Math.abs(r[1]-s[1])<1e-6,a=Boolean(e.shape&&(e.closed||i)),l=this.dxfContext.dxf.tables?.layer?.layers?.[e.layer],c=e.color??l?.color??x(this.dxfContext.colorIndex++,"polyline").color,d=this._buildLWPolylineFeature(e,n,a,c);a?this._applyPolygonRenderer(e,this._getLayerColor(e,c),d):this._applyLineRenderer(e,d)}async processArc(e){const t=(e.startAngle??0)*(Math.PI/180),n=(e.endAngle??0)*(Math.PI/180),r=n-t,s=e.layer||"default",i=this.dxfContext.dxf.tables?.layer?.layers?.[s],a=Math.abs(n-t),c=Math.min(720,Math.max(48,Math.ceil(a*e.radius/2))),d=r/c,y=[];for(let n=0;n<=c;n++){const r=t+d*n,s=e.center.x+e.radius*Math.cos(r),i=e.center.y+e.radius*Math.sin(r);y.push(new o({x:s,y:i,spatialReference:this.dxfContext.sourceSR}))}const p=(await l(y,this.dxfContext.targetSR)).filter((e=>void 0!==e.longitude&&void 0!==e.latitude)).map((e=>[e.longitude,e.latitude])),f={type:"Feature",geometry:{type:"LineString",coordinates:p},properties:{...e}};if(this.dxfContext.lastLineEnd&&this.dxfContext.lastLineLayer===s&&p[0]&&this._isSamePoint(this.dxfContext.lastLineEnd,p[0])){const e=this.dxfContext.lineFeatures.at(-1);if("LineString"===e?.geometry?.type){e.geometry.coordinates.push(...p.slice(1))}else this.dxfContext.lineFeatures.push(f)}else this.dxfContext.lineFeatures.push(f);this.dxfContext.lastLineEnd=p.at(-1)??void 0,this.dxfContext.lastLineLayer=s;const h=`${e.layer}-${e.type}-${e.handle}`;this.dxfContext.renderer_Object_Line[h]={value:s,symbol:{type:"simple-line",color:this.dxfContext.intToRGB(Number(i?.color??x(this.dxfContext.colorIndex++,"polyline").color)),width:1.5,style:(()=>{const t=this.dxfContext.dxf.tables.lineType?.lineTypes?.[e.lineType],o="object"==typeof t&&void 0!==t?t:void 0;return o?.pattern?{pattern:o.pattern.map((e=>parseFloat(e)))}:"solid"})()}}}lineToGeoJSON(){this.dxfContext.lineFeatures=this._mergeConnectedLinesAndArcs(this.dxfContext.lineFeatures);const e={type:"FeatureCollection",features:this.dxfContext.lineFeatures},t=new Blob([JSON.stringify(e)],{type:"application/json"}),o=URL.createObjectURL(t),r=new n({url:o,id:`dxf-lines-${this.dxfContext.sanitizedFileName}-${(new Date).getTime()}`,title:`${this.dxfContext.fileName} - Lines`,visible:!0,labelsVisible:!0,renderer:{type:"unique-value",field:"layer",defaultSymbol:{type:"simple-line",color:x(this.dxfContext.colorIndex++,"polyline").color,width:1.5,style:"solid"},uniqueValueInfos:Object.values(this.dxfContext.renderer_Object_Line).map((e=>{const t="object"==typeof e.symbol.style?"dash":e.symbol.style??"solid";return{value:e.value,symbol:{type:"simple-line",color:e.symbol.color??x(this.dxfContext.colorIndex++,"polyline").color,width:h(e.symbol?.width),style:t}}}))}});this.dxfContext.subLayers.push(r)}_getLayerColor(t,o){if("number"==typeof o)return this.dxfContext.intToRGB(o);if(Array.isArray(o))return o;if(o instanceof e)return o.toRgba();const n=x(this.dxfContext.colorIndex++,"polyline").color;if(n instanceof e)return n.toRgba();if(Array.isArray(n))return n;if("number"==typeof n)return this.dxfContext.intToRGB(n);const r=x(this.dxfContext.colorIndex++,"polyline").color;return r instanceof e?r.toRgba():Array.isArray(r)?r:[0,0,0,1]}_interpolateBulge(e,t,o,n=16){if(Math.abs(o)<1e-9)return[[t.x,t.y]];const r=t.x-e.x,s=t.y-e.y,i=Math.hypot(r,s);if(i<1e-9)return[[t.x,t.y]];const a=4*Math.atan(o),l=Math.abs(i/(2*Math.sin(a/2))),c=e.x+r/2,x=e.y+s/2,d=Math.sqrt(Math.max(0,l*l-i/2*(i/2))),y=c+d*(-s/i*Math.sign(o)),p=x+d*(r/i*Math.sign(o)),f=Math.atan2(e.y-p,e.x-y),h=[],u=a/n;for(let e=1;e<=n;e++){const t=f+e*u;h.push([y+l*Math.cos(t),p+l*Math.sin(t)])}return h}_buildBulgeInterpolatedPoints(e){const t=[];e.vertices.length>0&&e.vertices[0]&&t.push({x:e.vertices[0].x,y:e.vertices[0].y});for(let o=0;o<e.vertices.length-1;o++){const n=e.vertices[o],r=e.vertices[o+1];if(!n||!r)continue;const s=n.bulge??0,i=this._interpolateBulge(n,r,s,16);for(const[e,o]of i)t.push({x:e,y:o})}if((e.closed||e.shape)&&e.vertices.length>1){const o=e.vertices[0],n=e.vertices[e.vertices.length-1];if(o&&n&&(o.x!==n.x||o.y!==n.y)){const e=n.bulge??0,r=this._interpolateBulge(n,o,e,16);for(const[e,o]of r)t.push({x:e,y:o})}}return t}_buildLWPolylineFeature(e,t,o,n){return{type:"Feature",geometry:o?{type:"Polygon",coordinates:[t]}:{type:"LineString",coordinates:t},properties:{...e,color:n}}}async _getPolylineCoordinates(e){const t=e.vertices.map((e=>new o({x:e.x,y:e.y,spatialReference:this.dxfContext.sourceSR})));return(await l(t,this.dxfContext.targetSR)).filter((e=>!!e&&void 0!==e.longitude&&void 0!==e.latitude)).map((e=>[e.longitude,e.latitude]))}_ensureClosed(e){const t=e[0],o=e[e.length-1];t&&o&&(t[0]!==o[0]||t[1]!==o[1])&&e.push(t)}_buildPolylineFeature(e,t,o,n){return{type:"Feature",geometry:o?{type:"Polygon",coordinates:[t]}:{type:"LineString",coordinates:t},properties:{...e,color:n}}}_applyPolygonRenderer(t,o,n){this.dxfContext.polygonFeatures.push(n);const r=`${t.layer}-${t.type}-${t.handle}`,s=o instanceof e?o.toRgba():o;this.dxfContext.renderer_Object_Polygon[r]={value:t.layer||"default",symbol:{type:"simple-fill",style:t.closed?"solid":"none",color:s,outline:{color:s,width:t.width??1.5}}}}_applyLineRenderer(t,o){this.dxfContext.lineFeatures.push(o);const n=o.properties?.color;let r;if(n instanceof e)r=n.toRgba();else if(Array.isArray(n)&&n.every((e=>"number"==typeof e)))r=n;else{const e="number"==typeof n?n:0;r=this.dxfContext.intToRGB(e)}const s=`${t.layer}-${t.type}-${t.handle}`;this.dxfContext.renderer_Object_Line[s]={value:t.layer||"default",symbol:{type:"simple-line",color:r,width:t.lineweight||1.5,style:(()=>{const e=t.lineType&&this.dxfContext.dxf.tables.lineType?.lineTypes[t.lineType],o="object"==typeof e&&void 0!==e?e:void 0;return mapDXFLineTypeToEsri(t.lineType,o)})()}}}_isSamePoint(e,t,o=1e-6){return Math.abs(e[0]-t[0])<=o&&Math.abs(e[1]-t[1])<=o}_mergeConnectedLinesAndArcs(e){const t=[];for(const o of e){const e=t[t.length-1],n="LineString"===e?.geometry?.type,r="LineString"===o?.geometry?.type,s=n?e.geometry.coordinates:void 0,i=r?o.geometry.coordinates:void 0,a=s?.at(-1),l=i?.at(0);e&&a&&l&&e.properties?.layer===o.properties?.layer&&this._isSamePoint(a,l)?e.geometry.coordinates.push(...o.geometry.coordinates.slice(1)):t.push(o)}return t}}export class DxfToGeoJsonPolygonMapper{dxfContext;constructor(e){this.dxfContext=e}async processSolid(e){const t=e.points.map((e=>new o({x:e.x,y:e.y,spatialReference:this.dxfContext.sourceSR}))),n=(await l(t,this.dxfContext.targetSR)).filter((e=>!!e&&void 0!==e.longitude&&void 0!==e.latitude)).map((e=>[e.longitude,e.latitude]));if(n.length>0){const e=n[0],t=n[n.length-1];e[0]===t[0]&&e[1]===t[1]||n.push(e)}const r=this.dxfContext.dxf.tables?.layer?.layers?.[e.layer],s={type:"Feature",geometry:{type:"Polygon",coordinates:[n]},properties:{...e}};this.dxfContext.polygonFeatures.push(s);const i=r?.color??x(this.dxfContext.colorIndex++,"polygon").color,a=this.dxfContext.intToRGB(Number(i??0)),c=`${e.layer}-${e.type}-${e.handle}`;this.dxfContext.renderer_Object_Polygon[c]={value:e.layer||"default",symbol:{type:"simple-fill",style:"solid",color:[...a.slice(0,3),.5],outline:{color:this.dxfContext.intToRGB(Number(i??0)),width:1.5}}}}async processCircle(e){const t=e.center.x,n=e.center.y,r=Math.min(64,Math.max(16,Math.ceil(e.radius/5))),s=2*Math.PI/r,i=[];for(let a=0;a<=r;a++){const r=a*s,l=t+e.radius*Math.cos(r),c=n+e.radius*Math.sin(r);i.push(new o({x:l,y:c,spatialReference:this.dxfContext.sourceSR}))}const a=(await this.dxfContext.projectMany(i)).map((e=>[e[0],e[1]])),l=a[0],c=a[a.length-1];l&&c&&(l[0]!==c[0]||l[1]!==c[1])&&a.push(l);const d={type:"Feature",geometry:{type:"Polygon",coordinates:[a]},properties:{...e}};this.dxfContext.polygonFeatures.push(d);const y=this.dxfContext.dxf.tables?.layer?.layers?.[e.layer||"default"],p=e.color??y?.color??x(this.dxfContext.colorIndex++,"polygon").color;let f;f=Array.isArray(p)?p:"object"==typeof p&&"toRgba"in p?p.toRgba():this.dxfContext.intToRGB(p);const h=`${e.layer}-${e.type}-${e.handle}`;this.dxfContext.renderer_Object_Polygon[h]={value:e.layer||"default",symbol:{type:"simple-fill",style:"solid",color:f,outline:{color:f}}}}polygonToGeoJSON(){const t={type:"FeatureCollection",features:this.dxfContext.polygonFeatures},o=new Blob([JSON.stringify(t)],{type:"application/json"}),r=URL.createObjectURL(o);this.dxfContext.subLayers.push(new n({url:r,id:`dxf-polygons-${this.dxfContext.sanitizedFileName}-${(new Date).getTime()}`,title:`${this.dxfContext.fileName} - Polygons`,visible:!0,labelsVisible:!0,renderer:{type:"unique-value",field:"layer",defaultSymbol:(()=>{let e;const t=x(this.dxfContext.colorIndex++,"polygon");return t?.toJSON&&(e=t.toJSON()),{type:"simple-fill",style:d(e?.style),color:e?.color??x(this.dxfContext.colorIndex++,"polygon").color,outline:y(e?.outline)}})(),uniqueValueInfos:Object.values(this.dxfContext.renderer_Object_Polygon).map((t=>{const o=new i({color:t.symbol.outline?.color?new e(t.symbol.outline.color):new e(t.symbol.color??x(this.dxfContext.colorIndex++,"polygon").color),width:t.symbol.outline?.width??1.5}),n=t.symbol.color?[...t.symbol.color.slice(0,3),.3]:x(this.dxfContext.colorIndex++,"polygon").color,r=new s({style:"solid",color:new e(n),outline:o});return{value:t.value,symbol:r}}))}}))}}export class DxfToGeoJsonTextMapper{dxfContext;constructor(e){this.dxfContext=e}async processText(e){if(e.block)return;const[t,o]=await this.dxfContext.convertToSpatialReference(e.startPoint.x,e.startPoint.y);this.dxfContext.textFeatures.push({type:"Feature",geometry:{type:"Point",coordinates:[t,o]},properties:{...e}})}async processMText(e){const[t,o]=await this.dxfContext.convertToSpatialReference(e.position.x,e.position.y);this.dxfContext.textFeatures.push({type:"Feature",geometry:{type:"Point",coordinates:[t,o]},properties:{...e}})}async processAttDef(e){const[t,o]=await this.dxfContext.convertToSpatialReference(e.startPoint.x,e.startPoint.y),n=e.endPoint??e.startPoint,[r,s]=await this.dxfContext.convertToSpatialReference(n.x,n.y);this.dxfContext.textFeatures.push({type:"Feature",geometry:{type:"Point",coordinates:[t,o]},properties:{...e,startPoint:{x:t,y:o},endPoint:{x:r,y:s}}})}AnnotationToGeoJSON(){const e={1:"above-left",2:"above-center",3:"above-right",4:"center-left",5:"center-center",6:"center-right",7:"below-left",8:"below-center",9:"below-right"},t=new Map([[0,"left"],[2,"right"],[4,"center"]]),o=new Map([[0,"baseline"],[1,"bottom"],[2,"middle"],[3,"top"]]),n=this.dxfContext.textFeatures.map((n=>this._createTextGraphic(n,e,t,o))).filter((e=>null!==e)),s=new r({title:`${this.dxfContext.fileName??"dxf"} - Annotations`,id:`dxf-annotations-${this.dxfContext.sanitizedFileName??"dxf"}-${(new Date).getTime()}`,visible:!0,graphics:n});this.dxfContext.subLayers.push(s);const i=this.getMaximumFontSize(n);s.minScale=f(s.fullExtent??void 0,n.length,i),s.maxScale=0}getMaximumFontSize(e){let t=12;return e.forEach((e=>{if(!e)return;const o=e.attributes?.fontSize;"number"==typeof o&&Number.isFinite(o)&&(t=Math.max(t,o))})),t+2}_createTextGraphic(e,n,r,s){if("Point"!==e.geometry.type)return;const i=e.properties??{},l=this._getTextString(i);if(!l)return;const c=e.geometry.coordinates,x=new o({x:c[0],y:c[1],spatialReference:{wkid:4326}}),d=this._getTextColor(i),y=this._getFontSize(i),p=this._getRotation(i),{xoffset:f,yoffset:h}=this._getOffsets(i),{labelPlacement:u,horizontal:m,vertical:g}=this._getAlignment(i,n,r,s);return new t({geometry:x,symbol:new a({text:l,color:d,angle:p,xoffset:f,yoffset:h,horizontalAlignment:m,verticalAlignment:g,font:{family:"Arial",size:y}}),attributes:{...i,text:l,rotation:p,fontSize:y,horizontal:m,vertical:g,xoffset:f,yoffset:h,labelPlacement:u},popupTemplate:{title:"{text}",content:[{type:"fields",fieldInfos:Object.keys(i).map((e=>({fieldName:e,label:e})))}]}})}_getTextString(e){if(!e)return"";const t=String(e.text??"").trim(),o=String(e.prompt??"").trim(),n=t||o;return n||""}_getTextColor(e){const t=String(e?.layer||"0"),o=e?.color??this.dxfContext.dxf.tables?.layer?.layers?.[t]?.color??x(this.dxfContext.colorIndex++,"point").color;return this.dxfContext.intToRGB(o)}_getFontSize(e){let t=4*(e?.height??e?.textHeight??3);return t=Math.max(12,Math.min(t,30)),t}_getRotation(e){const t=String(e?.type??"").toUpperCase(),o=Number(e?.rotation??0);if("TEXT"===t)return-o;if("MTEXT"===t)return-o;if("ATTDEF"===t||"ATTRIB"===t){if(0!==o)return-o;if(e?.startPoint&&e?.endPoint){const{x:t,y:o}=e.startPoint,{x:n,y:r}=e.endPoint;if(t!==n||o!==r)return-180*Math.atan2(r-o,n-t)/Math.PI}return-o}if(e?.startPoint&&e?.endPoint){const{x:t,y:o}=e.startPoint,{x:n,y:r}=e.endPoint;return-180*Math.atan2(r-o,n-t)/Math.PI}return-o}_getOffsets(e){return{xoffset:Number(e?.xScale??0),yoffset:Number(e?.yScale??0)}}_getAlignment(e,t,o,n){return{labelPlacement:t[Number(e?.attachmentPoint??1)]??"above-left",horizontal:o.get(Number(e?.halign??e?.horizontalJustification))??"left",vertical:n.get(Number(e?.valign??e?.verticalJustification))??"baseline"}}}export class DxfToGeoJsonInsertBlockMapper{dxfContext;constructor(e){this.dxfContext=e}async processInsertFunction(e){if(!e.name||!this.dxfContext.dxf.blocks?.[e.name])return;const t=this.dxfContext.dxf.blocks[e.name],o=e.rotation||0,n={x:e.xScale??1,y:e.yScale??1,z:e.zScale??1},r=e.position||{x:0,y:0},[s,i]=await this.dxfContext.convertToSpatialReference(r.x,r.y);this._createInsertPointFeature(e,t,o,s,i);const a=(e.layer||"default").toString();this.dxfContext.renderer_Object_Point[a]=this._createLayerSymbol(a,e),await this._processBlockEntities(t,e,o,n,r)}async processPoint(t){const[o,n]=await this.dxfContext.convertToSpatialReference(t.position.x,t.position.y),r=this.dxfContext.dxf.header?.$PDMODE||0;let s="circle";if(32&~r)if(64&~r)switch(7&r){case 0:case 1:s="circle";break;case 2:s="cross";break;case 3:s="x"}else s="square";else s="circle";const i=(t.layer||"default").toString(),a=this.dxfContext.dxf.tables?.layer?.layers?.[i],l=t.color??a?.color??x(this.dxfContext.colorIndex++,"point").color,c=l instanceof e?l.toRgba():Array.isArray(l)?l:this.dxfContext.intToRGB(Number(l??0));this.dxfContext.pointFeatures.push({type:"Feature",geometry:{type:"Point",coordinates:[o,n]},properties:{...t}}),this.dxfContext.renderer_Object_Point[i]={value:i,symbol:{type:"simple-marker",style:s,size:this.dxfContext.dxf.header?.$PDSIZE||5,color:c}}}async processInsert(e){const t={...e};t.xScale=e.xScale??1,t.yScale=e.yScale??1,t.zScale=e.zScale??1,t.rotation=e.rotation??0,await this.processInsertFunction(t)}pointToGeoJSON(){const e={type:"FeatureCollection",features:this.dxfContext.pointFeatures},t=new Blob([JSON.stringify(e)],{type:"application/json"}),o=URL.createObjectURL(t),r=new n({url:o,id:`dxf-points-${this.dxfContext.sanitizedFileName}-${(new Date).getTime()}`,title:`${this.dxfContext.fileName} - Points`,labelsVisible:!0,renderer:{type:"unique-value",field:"layer",defaultSymbol:{type:"simple-marker",style:"circle",color:x(this.dxfContext.colorIndex++,"point").color,size:6},uniqueValueInfos:Object.values(this.dxfContext.renderer_Object_Point).map((e=>({value:e.value,symbol:{type:"simple-marker",style:"circle",size:e.symbol?.size||6,color:e.symbol.color??x(this.dxfContext.colorIndex++,"point").color}})))}});this.dxfContext.subLayers.push(r)}_createInsertPointFeature(e,t,o,n,r){this.dxfContext.pointFeatures.push({type:"Feature",geometry:{type:"Point",coordinates:[n,r]},properties:{layer:e.layer||"default",type:"INSERT",blockName:e.name,rotation:o,blockType:t?.name??e.name,color:e.color??this.dxfContext.dxf.tables?.layer?.layers?.[e.layer]?.color??x(this.dxfContext.colorIndex++,"polyline").color,text:t?.name??e.name}})}_createLayerSymbol(e,t){return{value:e,symbol:{type:"simple-marker",style:"circle",size:5,color:this.dxfContext.intToRGB(this.dxfContext.dxf.tables?.layer?.layers?.[t.layer]?.color??0)}}}_normalizeBlockEntities(e){const t=e.entities;return Array.isArray(t)?t:void 0===t?[]:"function"==typeof t[Symbol.iterator]?Array.from(t):Array.isArray(t.entities)?t.entities:"object"==typeof t&&void 0!==t?Object.values(t):[]}async _processBlockEntities(e,t,o,n,r){const s=this._normalizeBlockEntities(e);if(0!==s.length)for(const e of s){if(!e||"object"!=typeof e)continue;const s=e.type;if("BLOCK"===s||"ENDBLK"===s)continue;const i=JSON.parse(JSON.stringify(e));if(i.layer=e.layer&&"0"!==e.layer?e.layer:String(t.layer),0===e.color)i.color=t.color;else if(256===e.color||void 0===e.color){const e=this.dxfContext.dxf.tables?.layer?.layers?.[String(t.layer)];i.color=e?.color}try{this._transformEntityGeometry(i,n,o,r),this._adjustEntityAttributes(i,n,o,t.name),await this.dxfContext.dxfEntities([i])}catch{continue}}}_transformEntityGeometry(e,t,o,n){const r=o*Math.PI/180,s=(e,o)=>({x:e*t.x*Math.cos(r)-o*t.y*Math.sin(r)+n.x,y:e*t.x*Math.sin(r)+o*t.y*Math.cos(r)+n.y});e.vertices&&(e.vertices=e.vertices.map((e=>{const t=s(e.x,e.y);return{x:t.x,y:t.y,bulge:e.bulge}}))),e.center&&(e.center=s(e.center.x,e.center.y)),e.position&&(e.position=s(e.position.x,e.position.y))}_adjustEntityAttributes(e,t,o,n){e.radius&&(e.radius*=Math.max(t.x,t.y)),e.height&&(e.height*=t.y),void 0!==e.rotation&&(e.rotation=(e.rotation+o)%360),e.blockName=String(n)}}export function mapDXFLineTypeToEsri(e,t){if(!e)return"solid";const o=e.toUpperCase(),n=function(e,t){if(!e)return;const o=e.toUpperCase().trim(),n={BYLAYER:"solid",BYBLOCK:"solid",CONTINUOUS:"solid",HIDDEN:"dash",DASHED:"dash",DASHEDX2:"dash",DASHED2:"dash",CENTER:"dash-dot",CENTERX2:"dash-dot",CENTER2:"dash-dot",DASHDOT:"dash-dot",DOTTED:"dot",DIVIDE:"short-dash",DIVIDEX2:"short-dash-dot",DIVIDE2:"short-dash-dot"};if(n[o])return n[o];if(t?.length){const e=Math.abs(t[0]??0),o=Math.abs(t[1]??0);if(2===t.length)return e<8&&o<6?"short-dash":e>=8&&e<=15&&o>=6&&o<=15?"dash":"long-dash";if(4===t.length)return e<6&&o<6?"short-dash-dot":e>=6&&e<=15&&o>=6&&o<=15?"dash-dot":"long-dash-dot"}return}(o,t?.pattern?.map((e=>parseFloat(e))));if(n)return n;const r=function(e){const t=e.toUpperCase();return t.includes("LONG")?"long-dash":t.includes("DOUBLE")?"long-dash-dot":t.includes("PHANTOM")?"dash-dot":void 0}(o);if(r)return r;const s=function(e){if(e?.pattern&&Array.isArray(e.pattern)){const t=e.pattern,o=t.some((e=>parseFloat(e)>.2)),n=t.some((e=>0===parseFloat(e)));return o&&!n?"dash":!o&&n?"dot":o&&n?"dash-dot":"solid"}return}(t);return s||"solid"}export class DxfEntityProcessor{dxfContext;entityHandlers;constructor(e,t,o={}){const n={dxf:{header:{},tables:{viewPort:{handle:"",ownerHandle:"",viewPorts:[]},lineType:{handle:"",ownerHandle:"",lineTypes:{}},layer:{handle:"",ownerHandle:"",layers:{}}},entities:[],blocks:{}},renderer_Object_Point:{},renderer_Object_Line:{},renderer_Object_Polygon:{},sourceSR:e,targetSR:t,subLayers:[],pointFeatures:[],lineFeatures:[],polygonFeatures:[],textFeatures:[],async dxfEntities(){},convertToSpatialReference:async()=>[0,0],projectMany:async()=>[],intToRGB:p,colorIndex:0,...o};n.dxfToGeoJsonLineMapper=new DxfToGeoJsonLineMapper(n),n.dxfToGeoJsonPolygonMapper=new DxfToGeoJsonPolygonMapper(n),n.dxfToGeoJsonTextMapper=new DxfToGeoJsonTextMapper(n),n.dxfToGeoJsonInsertBlockMapper=new DxfToGeoJsonInsertBlockMapper(n),this.dxfContext=n,this.dxfContext.convertToSpatialReference=(e,t)=>this.convertToSpatialReference(e,t),this.dxfContext.projectMany=e=>this.projectMany(e),this.dxfContext.dxfEntities=async e=>this.process(e),this.entityHandlers={POINT:e=>this.dxfContext.dxfToGeoJsonInsertBlockMapper.processPoint(e),INSERT:e=>this.dxfContext.dxfToGeoJsonInsertBlockMapper.processInsert(e),LINE:async e=>{e.vertices?.length>=2&&await this.dxfContext.dxfToGeoJsonLineMapper.processLine(e)},ARC:async e=>{e.center&&void 0!==e.radius&&await this.dxfContext.dxfToGeoJsonLineMapper.processArc(e)},LWPOLYLINE:async e=>{Array.isArray(e.vertices)&&await this.dxfContext.dxfToGeoJsonLineMapper.processLWPolyline(e)},POLYLINE:async e=>{Array.isArray(e.vertices)&&await this.dxfContext.dxfToGeoJsonLineMapper.processPolyline(e)},SOLID:async e=>{e.points.length>=3&&await this.dxfContext.dxfToGeoJsonPolygonMapper.processSolid(e)},CIRCLE:async e=>{e.center&&e.radius&&await this.dxfContext.dxfToGeoJsonPolygonMapper.processCircle(e)},TEXT:e=>this.dxfContext.dxfToGeoJsonTextMapper.processText(e),MTEXT:async e=>{e.position&&await this.dxfContext.dxfToGeoJsonTextMapper.processMText(e)},ATTDEF:async e=>{e.startPoint&&await this.dxfContext.dxfToGeoJsonTextMapper.processAttDef(e)}}}getContext(){return this.dxfContext}async convertToSpatialReference(e,t){const n=new o({x:e,y:t,spatialReference:this.dxfContext.sourceSR}),[r]=await l([n],this.dxfContext.targetSR);return r?[r.longitude??0,r.latitude??0]:[0,0]}async projectMany(e){return(await l(e,this.dxfContext.targetSR)).map(((t,o)=>{const n=e[o];return[t?.longitude??n.x,t?.latitude??n.y]}))}async process(e){const t=Array.isArray(e)?e:[e];for(const e of t){if(!e||"BLOCK"===e.type||"ENDBLK"===e.type)continue;const t=this.entityHandlers[e.type];t&&await t(e)}}async processAll(){if(this.dxfContext.dxf.entities?.length>0){const e=50;for(let t=0;t<this.dxfContext.dxf.entities.length;t+=e){const o=this.dxfContext.dxf.entities.slice(t,t+e);await c(),await this.process(o)}}return await Promise.all([this.dxfContext.polygonFeatures.length>0&&this.dxfContext.dxfToGeoJsonPolygonMapper.polygonToGeoJSON(),this.dxfContext.lineFeatures.length>0&&this.dxfContext.dxfToGeoJsonLineMapper.lineToGeoJSON(),this.dxfContext.pointFeatures.length>0&&this.dxfContext.dxfToGeoJsonInsertBlockMapper.pointToGeoJSON(),this.dxfContext.textFeatures.length>0&&this.dxfContext.dxfToGeoJsonTextMapper.AnnotationToGeoJSON()].filter(Boolean)),this.dxfContext.subLayers}}
1
+ import e from"@arcgis/core/Color";import t from"@arcgis/core/Graphic";import o from"@arcgis/core/geometry/Point";import n from"@arcgis/core/geometry/SpatialReference";import r from"@arcgis/core/layers/GeoJSONLayer";import s from"@arcgis/core/layers/GraphicsLayer";import i from"@arcgis/core/symbols/SimpleFillSymbol";import a from"@arcgis/core/symbols/SimpleLineSymbol";import l from"@arcgis/core/symbols/TextSymbol.js";import{project as c}from"../../utilities/geometry.js";import{delay as x}from"../../utilities/promise.js";import{getDefaultSymbol as d}from"../convert.js";import{normalizeFillStyle as y,normalizeLineOutline as p,intToRGB as f,deriveAnnotationMinScale as h,sanitizeSymbolWidth as u}from"./_dxfFunctions.js";export class DxfToGeoJsonLineMapper{dxfContext;constructor(e){this.dxfContext=e,this.dxfContext.lastLineEnd=void 0,this.dxfContext.lastLineLayer=void 0}async processLine(e){const{vertices:t}=e;if(!t||t.length<2)return;const o=t[0],n=t[1];if(!o||!n)return;const[r,s]=await Promise.all([this.dxfContext.convertToSpatialReference(o.x,o.y),this.dxfContext.convertToSpatialReference(n.x,n.y)]),i=e.layer||"default",a={type:"Feature",geometry:{type:"LineString",coordinates:[r,s]},properties:{...e}};if(this.dxfContext.lastLineEnd&&this.dxfContext.lastLineLayer===i&&this._isSamePoint(this.dxfContext.lastLineEnd,r)){const e=this.dxfContext.lineFeatures.at(-1);if("LineString"===e?.geometry?.type){e.geometry.coordinates.push(s)}else this.dxfContext.lineFeatures.push(a)}else this.dxfContext.lineFeatures.push(a);this.dxfContext.lastLineEnd=s,this.dxfContext.lastLineLayer=i;const l=this.dxfContext.dxf.tables?.layer?.layers?.[i],c=e.color??l?.color??d(this.dxfContext.colorIndex++,"polyline").color,x=this._getLayerColor(e,c),y=`${e.layer}-${e.type}-${e.handle}`;this.dxfContext.renderer_Object_Line[y]={value:e.layer||"default",symbol:{type:"simple-line",color:x,width:e.lineweight||1.5,style:(()=>{const t=e.lineType&&this.dxfContext.dxf.tables?.lineType?.lineTypes?.[e.lineType];return"object"==typeof t&&t?.pattern?{pattern:t.pattern.map((e=>parseFloat(e)))}:"solid"})()}}}async processPolyline(t){const o=await this._getPolylineCoordinates(t),n=!!t.closed;n&&o.length>0&&this._ensureClosed(o);const r=this.dxfContext.dxf.tables?.layer?.layers?.[t.layer];let s;s=t.color,void 0!==s&&0!==s&&256!==s||(s=r?.color),void 0===s&&(s=d(this.dxfContext.colorIndex++,"polyline")?.color??new e("black"));const i="number"==typeof s?this.dxfContext.intToRGB(s):s,a=this._buildPolylineFeature(t,o,n,s);if(n)if(Array.isArray(i))this._applyPolygonRenderer(t,i,a);else if(i&&"object"==typeof i&&"r"in i){const e=[i.r,i.g,i.b,1];this._applyPolygonRenderer(t,e,a)}else{const o=d(this.dxfContext.colorIndex++,"polygon").color,n=o instanceof e?o.toRgba():o;this._applyPolygonRenderer(t,n,a)}else this._applyLineRenderer(t,a)}async processLWPolyline(e){const t=this._buildBulgeInterpolatedPoints(e),n=await this.dxfContext.projectMany(t.map((e=>new o({x:e.x,y:e.y,spatialReference:this.dxfContext.sourceSR})))),r=n[0],s=n[n.length-1],i=!!r&&!!s&&Math.abs(r[0]-s[0])<1e-6&&Math.abs(r[1]-s[1])<1e-6,a=Boolean(e.shape&&(e.closed||i)),l=this.dxfContext.dxf.tables?.layer?.layers?.[e.layer],c=e.color??l?.color??d(this.dxfContext.colorIndex++,"polyline").color,x=this._buildLWPolylineFeature(e,n,a,c);a?this._applyPolygonRenderer(e,this._getLayerColor(e,c),x):this._applyLineRenderer(e,x)}async processArc(e){const t=(e.startAngle??0)*(Math.PI/180),n=(e.endAngle??0)*(Math.PI/180),r=n-t,s=e.layer||"default",i=this.dxfContext.dxf.tables?.layer?.layers?.[s],a=Math.abs(n-t),l=Math.min(720,Math.max(48,Math.ceil(a*e.radius/2))),x=r/l,y=[];for(let n=0;n<=l;n++){const r=t+x*n,s=e.center.x+e.radius*Math.cos(r),i=e.center.y+e.radius*Math.sin(r);y.push(new o({x:s,y:i,spatialReference:this.dxfContext.sourceSR}))}const p=(await c(y,this.dxfContext.targetSR)).filter((e=>void 0!==e.longitude&&void 0!==e.latitude)).map((e=>[e.longitude,e.latitude])),f={type:"Feature",geometry:{type:"LineString",coordinates:p},properties:{...e}};if(this.dxfContext.lastLineEnd&&this.dxfContext.lastLineLayer===s&&p[0]&&this._isSamePoint(this.dxfContext.lastLineEnd,p[0])){const e=this.dxfContext.lineFeatures.at(-1);if("LineString"===e?.geometry?.type){e.geometry.coordinates.push(...p.slice(1))}else this.dxfContext.lineFeatures.push(f)}else this.dxfContext.lineFeatures.push(f);this.dxfContext.lastLineEnd=p.at(-1)??void 0,this.dxfContext.lastLineLayer=s;const h=`${e.layer}-${e.type}-${e.handle}`;this.dxfContext.renderer_Object_Line[h]={value:s,symbol:{type:"simple-line",color:this.dxfContext.intToRGB(Number(i?.color??d(this.dxfContext.colorIndex++,"polyline").color)),width:1.5,style:(()=>{const t=this.dxfContext.dxf.tables.lineType?.lineTypes?.[e.lineType],o="object"==typeof t&&void 0!==t?t:void 0;return o?.pattern?{pattern:o.pattern.map((e=>parseFloat(e)))}:"solid"})()}}}lineToGeoJSON(){this.dxfContext.lineFeatures=this._mergeConnectedLinesAndArcs(this.dxfContext.lineFeatures);const e={type:"FeatureCollection",features:this.dxfContext.lineFeatures},t=new Blob([JSON.stringify(e)],{type:"application/json"}),o=URL.createObjectURL(t),n=new r({url:o,id:`dxf-lines-${this.dxfContext.sanitizedFileName}-${(new Date).getTime()}`,title:`${this.dxfContext.fileName} - Lines`,visible:!0,labelsVisible:!0,renderer:{type:"unique-value",field:"layer",defaultSymbol:{type:"simple-line",color:d(this.dxfContext.colorIndex++,"polyline").color,width:1.5,style:"solid"},uniqueValueInfos:Object.values(this.dxfContext.renderer_Object_Line).map((e=>{const t="object"==typeof e.symbol.style?"dash":e.symbol.style??"solid";return{value:e.value,symbol:{type:"simple-line",color:e.symbol.color??d(this.dxfContext.colorIndex++,"polyline").color,width:u(e.symbol?.width),style:t}}}))}});this.dxfContext.subLayers.push(n)}_getLayerColor(t,o){if("number"==typeof o)return this.dxfContext.intToRGB(o);if(Array.isArray(o))return o;if(o instanceof e)return o.toRgba();const n=d(this.dxfContext.colorIndex++,"polyline").color;if(n instanceof e)return n.toRgba();if(Array.isArray(n))return n;if("number"==typeof n)return this.dxfContext.intToRGB(n);const r=d(this.dxfContext.colorIndex++,"polyline").color;return r instanceof e?r.toRgba():Array.isArray(r)?r:[0,0,0,1]}_interpolateBulge(e,t,o,n=16){if(Math.abs(o)<1e-9)return[[t.x,t.y]];const r=t.x-e.x,s=t.y-e.y,i=Math.hypot(r,s);if(i<1e-9)return[[t.x,t.y]];const a=4*Math.atan(o),l=Math.abs(i/(2*Math.sin(a/2))),c=e.x+r/2,x=e.y+s/2,d=Math.sqrt(Math.max(0,l*l-i/2*(i/2))),y=c+d*(-s/i*Math.sign(o)),p=x+d*(r/i*Math.sign(o)),f=Math.atan2(e.y-p,e.x-y),h=[],u=a/n;for(let e=1;e<=n;e++){const t=f+e*u;h.push([y+l*Math.cos(t),p+l*Math.sin(t)])}return h}_buildBulgeInterpolatedPoints(e){const t=[];e.vertices.length>0&&e.vertices[0]&&t.push({x:e.vertices[0].x,y:e.vertices[0].y});for(let o=0;o<e.vertices.length-1;o++){const n=e.vertices[o],r=e.vertices[o+1];if(!n||!r)continue;const s=n.bulge??0,i=this._interpolateBulge(n,r,s,16);for(const[e,o]of i)t.push({x:e,y:o})}if((e.closed||e.shape)&&e.vertices.length>1){const o=e.vertices[0],n=e.vertices[e.vertices.length-1];if(o&&n&&(o.x!==n.x||o.y!==n.y)){const e=n.bulge??0,r=this._interpolateBulge(n,o,e,16);for(const[e,o]of r)t.push({x:e,y:o})}}return t}_buildLWPolylineFeature(e,t,o,n){return{type:"Feature",geometry:o?{type:"Polygon",coordinates:[t]}:{type:"LineString",coordinates:t},properties:{...e,color:n}}}async _getPolylineCoordinates(e){const t=e.vertices.map((e=>new o({x:e.x,y:e.y,spatialReference:this.dxfContext.sourceSR})));return(await c(t,this.dxfContext.targetSR)).filter((e=>!!e&&void 0!==e.longitude&&void 0!==e.latitude)).map((e=>[e.longitude,e.latitude]))}_ensureClosed(e){const t=e[0],o=e[e.length-1];t&&o&&(t[0]!==o[0]||t[1]!==o[1])&&e.push(t)}_buildPolylineFeature(e,t,o,n){return{type:"Feature",geometry:o?{type:"Polygon",coordinates:[t]}:{type:"LineString",coordinates:t},properties:{...e,color:n}}}_applyPolygonRenderer(t,o,n){this.dxfContext.polygonFeatures.push(n);const r=`${t.layer}-${t.type}-${t.handle}`,s=o instanceof e?o.toRgba():o;this.dxfContext.renderer_Object_Polygon[r]={value:t.layer||"default",symbol:{type:"simple-fill",style:t.closed?"solid":"none",color:s,outline:{color:s,width:t.width??1.5}}}}_applyLineRenderer(t,o){this.dxfContext.lineFeatures.push(o);const n=o.properties?.color;let r;if(n instanceof e)r=n.toRgba();else if(Array.isArray(n)&&n.every((e=>"number"==typeof e)))r=n;else{const e="number"==typeof n?n:0;r=this.dxfContext.intToRGB(e)}const s=`${t.layer}-${t.type}-${t.handle}`;this.dxfContext.renderer_Object_Line[s]={value:t.layer||"default",symbol:{type:"simple-line",color:r,width:t.lineweight||1.5,style:(()=>{const e=t.lineType&&this.dxfContext.dxf.tables.lineType?.lineTypes[t.lineType],o="object"==typeof e&&void 0!==e?e:void 0;return mapDXFLineTypeToEsri(t.lineType,o)})()}}}_isSamePoint(e,t,o=1e-6){return Math.abs(e[0]-t[0])<=o&&Math.abs(e[1]-t[1])<=o}_mergeConnectedLinesAndArcs(e){const t=[];for(const o of e){const e=t[t.length-1],n="LineString"===e?.geometry?.type,r="LineString"===o?.geometry?.type,s=n?e.geometry.coordinates:void 0,i=r?o.geometry.coordinates:void 0,a=s?.at(-1),l=i?.at(0);e&&a&&l&&e.properties?.layer===o.properties?.layer&&this._isSamePoint(a,l)?e.geometry.coordinates.push(...o.geometry.coordinates.slice(1)):t.push(o)}return t}}export class DxfToGeoJsonPolygonMapper{dxfContext;constructor(e){this.dxfContext=e}async processSolid(e){const t=e.points.map((e=>new o({x:e.x,y:e.y,spatialReference:this.dxfContext.sourceSR}))),n=(await c(t,this.dxfContext.targetSR)).filter((e=>!!e&&void 0!==e.longitude&&void 0!==e.latitude)).map((e=>[e.longitude,e.latitude]));if(n.length>0){const e=n[0],t=n[n.length-1];e[0]===t[0]&&e[1]===t[1]||n.push(e)}const r=this.dxfContext.dxf.tables?.layer?.layers?.[e.layer],s={type:"Feature",geometry:{type:"Polygon",coordinates:[n]},properties:{...e}};this.dxfContext.polygonFeatures.push(s);const i=r?.color??d(this.dxfContext.colorIndex++,"polygon").color,a=this.dxfContext.intToRGB(Number(i??0)),l=`${e.layer}-${e.type}-${e.handle}`;this.dxfContext.renderer_Object_Polygon[l]={value:e.layer||"default",symbol:{type:"simple-fill",style:"solid",color:[...a.slice(0,3),.5],outline:{color:this.dxfContext.intToRGB(Number(i??0)),width:1.5}}}}async processCircle(e){const t=e.center.x,n=e.center.y,r=Math.min(64,Math.max(16,Math.ceil(e.radius/5))),s=2*Math.PI/r,i=[];for(let a=0;a<=r;a++){const r=a*s,l=t+e.radius*Math.cos(r),c=n+e.radius*Math.sin(r);i.push(new o({x:l,y:c,spatialReference:this.dxfContext.sourceSR}))}const a=(await this.dxfContext.projectMany(i)).map((e=>[e[0],e[1]])),l=a[0],c=a[a.length-1];l&&c&&(l[0]!==c[0]||l[1]!==c[1])&&a.push(l);const x={type:"Feature",geometry:{type:"Polygon",coordinates:[a]},properties:{...e}};this.dxfContext.polygonFeatures.push(x);const y=this.dxfContext.dxf.tables?.layer?.layers?.[e.layer||"default"],p=e.color??y?.color??d(this.dxfContext.colorIndex++,"polygon").color;let f;f=Array.isArray(p)?p:"object"==typeof p&&"toRgba"in p?p.toRgba():this.dxfContext.intToRGB(p);const h=`${e.layer}-${e.type}-${e.handle}`;this.dxfContext.renderer_Object_Polygon[h]={value:e.layer||"default",symbol:{type:"simple-fill",style:"solid",color:f,outline:{color:f}}}}polygonToGeoJSON(){const t={type:"FeatureCollection",features:this.dxfContext.polygonFeatures},o=new Blob([JSON.stringify(t)],{type:"application/json"}),n=URL.createObjectURL(o);this.dxfContext.subLayers.push(new r({url:n,id:`dxf-polygons-${this.dxfContext.sanitizedFileName}-${(new Date).getTime()}`,title:`${this.dxfContext.fileName} - Polygons`,visible:!0,labelsVisible:!0,renderer:{type:"unique-value",field:"layer",defaultSymbol:(()=>{let e;const t=d(this.dxfContext.colorIndex++,"polygon");return t?.toJSON&&(e=t.toJSON()),{type:"simple-fill",style:y(e?.style),color:e?.color??d(this.dxfContext.colorIndex++,"polygon").color,outline:p(e?.outline)}})(),uniqueValueInfos:Object.values(this.dxfContext.renderer_Object_Polygon).map((t=>{const o=new a({color:t.symbol.outline?.color?new e(t.symbol.outline.color):new e(t.symbol.color??d(this.dxfContext.colorIndex++,"polygon").color),width:t.symbol.outline?.width??1.5}),n=t.symbol.color?[...t.symbol.color.slice(0,3),.3]:d(this.dxfContext.colorIndex++,"polygon").color,r=new i({style:"solid",color:new e(n),outline:o});return{value:t.value,symbol:r}}))}}))}}export class DxfToGeoJsonTextMapper{dxfContext;constructor(e){this.dxfContext=e}async processText(e){if(e.block)return;const[t,o]=await this.dxfContext.convertToSpatialReference(e.startPoint.x,e.startPoint.y);this.dxfContext.textFeatures.push({type:"Feature",geometry:{type:"Point",coordinates:[t,o]},properties:{...e}})}async processMText(e){const[t,o]=await this.dxfContext.convertToSpatialReference(e.position.x,e.position.y);this.dxfContext.textFeatures.push({type:"Feature",geometry:{type:"Point",coordinates:[t,o]},properties:{...e}})}async processAttDef(e){const[t,o]=await this.dxfContext.convertToSpatialReference(e.startPoint.x,e.startPoint.y),n=e.endPoint??e.startPoint,[r,s]=await this.dxfContext.convertToSpatialReference(n.x,n.y);this.dxfContext.textFeatures.push({type:"Feature",geometry:{type:"Point",coordinates:[t,o]},properties:{...e,startPoint:{x:t,y:o},endPoint:{x:r,y:s}}})}AnnotationToGeoJSON(){const e={1:"above-left",2:"above-center",3:"above-right",4:"center-left",5:"center-center",6:"center-right",7:"below-left",8:"below-center",9:"below-right"},t=new Map([[0,"left"],[2,"right"],[4,"center"]]),o=new Map([[0,"baseline"],[1,"bottom"],[2,"middle"],[3,"top"]]),n=this.dxfContext.textFeatures.map((n=>this._createTextGraphic(n,e,t,o))).filter((e=>null!==e)),r=new s({title:`${this.dxfContext.fileName??"dxf"} - Annotations`,id:`dxf-annotations-${this.dxfContext.sanitizedFileName??"dxf"}-${(new Date).getTime()}`,visible:!0,graphics:n});this.dxfContext.subLayers.push(r);const i=this.getMaximumFontSize(n);r.minScale=h(r.fullExtent??void 0,n.length,i),r.maxScale=0}getMaximumFontSize(e){let t=12;return e.forEach((e=>{if(!e)return;const o=e.attributes?.fontSize;"number"==typeof o&&Number.isFinite(o)&&(t=Math.max(t,o))})),t+2}_createTextGraphic(e,n,r,s){if("Point"!==e.geometry.type)return;const i=e.properties??{},a=this._getTextString(i);if(!a)return;const c=e.geometry.coordinates,x=new o({x:c[0],y:c[1],spatialReference:{wkid:4326}}),d=this._getTextColor(i),y=this._getFontSize(i),p=this._getRotation(i),{xoffset:f,yoffset:h}=this._getOffsets(i),{labelPlacement:u,horizontal:m,vertical:g}=this._getAlignment(i,n,r,s);return new t({geometry:x,symbol:new l({text:a,color:d,angle:p,xoffset:f,yoffset:h,horizontalAlignment:m,verticalAlignment:g,font:{family:"Arial",size:y}}),attributes:{...i,text:a,rotation:p,fontSize:y,horizontal:m,vertical:g,xoffset:f,yoffset:h,labelPlacement:u},popupTemplate:{title:"{text}",content:[{type:"fields",fieldInfos:Object.keys(i).map((e=>({fieldName:e,label:e})))}]}})}_getTextString(e){if(!e)return"";const t=String(e.text??"").trim(),o=String(e.prompt??"").trim(),n=t||o;return n||""}_getTextColor(e){const t=String(e?.layer||"0"),o=e?.color??this.dxfContext.dxf.tables?.layer?.layers?.[t]?.color??d(this.dxfContext.colorIndex++,"point").color;return this.dxfContext.intToRGB(o)}_getFontSize(e){let t=4*(e?.height??e?.textHeight??3);return t=Math.max(12,Math.min(t,30)),t}_getRotation(e){const t=String(e?.type??"").toUpperCase(),o=Number(e?.rotation??0);if("TEXT"===t)return-o;if("MTEXT"===t)return-o;if("ATTDEF"===t||"ATTRIB"===t){if(0!==o)return-o;if(e?.startPoint&&e?.endPoint){const{x:t,y:o}=e.startPoint,{x:n,y:r}=e.endPoint;if(t!==n||o!==r)return-180*Math.atan2(r-o,n-t)/Math.PI}return-o}if(e?.startPoint&&e?.endPoint){const{x:t,y:o}=e.startPoint,{x:n,y:r}=e.endPoint;return-180*Math.atan2(r-o,n-t)/Math.PI}return-o}_getOffsets(e){return{xoffset:Number(e?.xScale??0),yoffset:Number(e?.yScale??0)}}_getAlignment(e,t,o,n){return{labelPlacement:t[Number(e?.attachmentPoint??1)]??"above-left",horizontal:o.get(Number(e?.halign??e?.horizontalJustification))??"left",vertical:n.get(Number(e?.valign??e?.verticalJustification))??"baseline"}}}export class DxfToGeoJsonInsertBlockMapper{dxfContext;constructor(e){this.dxfContext=e}async processInsertFunction(e){if(!e.name||!this.dxfContext.dxf.blocks?.[e.name])return;const t=this.dxfContext.dxf.blocks[e.name],o=e.rotation||0,n={x:e.xScale??1,y:e.yScale??1,z:e.zScale??1},r=e.position||{x:0,y:0},[s,i]=await this.dxfContext.convertToSpatialReference(r.x,r.y);this._createInsertPointFeature(e,t,o,s,i);const a=(e.layer||"default").toString();this.dxfContext.renderer_Object_Point[a]=this._createLayerSymbol(a,e),await this._processBlockEntities(t,e,o,n,r)}async processPoint(t){const[o,n]=await this.dxfContext.convertToSpatialReference(t.position.x,t.position.y),r=this.dxfContext.dxf.header?.$PDMODE||0;let s="circle";if(32&~r)if(64&~r)switch(7&r){case 0:case 1:s="circle";break;case 2:s="cross";break;case 3:s="x"}else s="square";else s="circle";const i=(t.layer||"default").toString(),a=this.dxfContext.dxf.tables?.layer?.layers?.[i],l=t.color??a?.color??d(this.dxfContext.colorIndex++,"point").color,c=l instanceof e?l.toRgba():Array.isArray(l)?l:this.dxfContext.intToRGB(Number(l??0));this.dxfContext.pointFeatures.push({type:"Feature",geometry:{type:"Point",coordinates:[o,n]},properties:{...t}}),this.dxfContext.renderer_Object_Point[i]={value:i,symbol:{type:"simple-marker",style:s,size:this.dxfContext.dxf.header?.$PDSIZE||5,color:c}}}async processInsert(e){const t={...e};t.xScale=e.xScale??1,t.yScale=e.yScale??1,t.zScale=e.zScale??1,t.rotation=e.rotation??0,await this.processInsertFunction(t)}pointToGeoJSON(){const e={type:"FeatureCollection",features:this.dxfContext.pointFeatures},t=new Blob([JSON.stringify(e)],{type:"application/json"}),o=URL.createObjectURL(t),n=new r({url:o,id:`dxf-points-${this.dxfContext.sanitizedFileName}-${(new Date).getTime()}`,title:`${this.dxfContext.fileName} - Points`,labelsVisible:!0,renderer:{type:"unique-value",field:"layer",defaultSymbol:{type:"simple-marker",style:"circle",color:d(this.dxfContext.colorIndex++,"point").color,size:6},uniqueValueInfos:Object.values(this.dxfContext.renderer_Object_Point).map((e=>({value:e.value,symbol:{type:"simple-marker",style:"circle",size:e.symbol?.size||6,color:e.symbol.color??d(this.dxfContext.colorIndex++,"point").color}})))}});this.dxfContext.subLayers.push(n)}_createInsertPointFeature(e,t,o,n,r){this.dxfContext.pointFeatures.push({type:"Feature",geometry:{type:"Point",coordinates:[n,r]},properties:{layer:e.layer||"default",type:"INSERT",blockName:e.name,rotation:o,blockType:t?.name??e.name,color:e.color??this.dxfContext.dxf.tables?.layer?.layers?.[e.layer]?.color??d(this.dxfContext.colorIndex++,"polyline").color,text:t?.name??e.name}})}_createLayerSymbol(e,t){return{value:e,symbol:{type:"simple-marker",style:"circle",size:5,color:this.dxfContext.intToRGB(this.dxfContext.dxf.tables?.layer?.layers?.[t.layer]?.color??0)}}}_normalizeBlockEntities(e){const t=e.entities;return Array.isArray(t)?t:void 0===t?[]:"function"==typeof t[Symbol.iterator]?Array.from(t):Array.isArray(t.entities)?t.entities:"object"==typeof t&&void 0!==t?Object.values(t):[]}async _processBlockEntities(e,t,o,n,r){const s=this._normalizeBlockEntities(e);if(0!==s.length)for(const e of s){if(!e||"object"!=typeof e)continue;const s=e.type;if("BLOCK"===s||"ENDBLK"===s)continue;const i=JSON.parse(JSON.stringify(e));if(i.layer=e.layer&&"0"!==e.layer?e.layer:String(t.layer),0===e.color)i.color=t.color;else if(256===e.color||void 0===e.color){const e=this.dxfContext.dxf.tables?.layer?.layers?.[String(t.layer)];i.color=e?.color}try{this._transformEntityGeometry(i,n,o,r),this._adjustEntityAttributes(i,n,o,t.name),await this.dxfContext.dxfEntities([i])}catch{continue}}}_transformEntityGeometry(e,t,o,n){const r=o*Math.PI/180,s=(e,o)=>({x:e*t.x*Math.cos(r)-o*t.y*Math.sin(r)+n.x,y:e*t.x*Math.sin(r)+o*t.y*Math.cos(r)+n.y});e.vertices&&(e.vertices=e.vertices.map((e=>{const t=s(e.x,e.y);return{x:t.x,y:t.y,bulge:e.bulge}}))),e.center&&(e.center=s(e.center.x,e.center.y)),e.position&&(e.position=s(e.position.x,e.position.y))}_adjustEntityAttributes(e,t,o,n){e.radius&&(e.radius*=Math.max(t.x,t.y)),e.height&&(e.height*=t.y),void 0!==e.rotation&&(e.rotation=(e.rotation+o)%360),e.blockName=String(n)}}export function mapDXFLineTypeToEsri(e,t){if(!e)return"solid";const o=e.toUpperCase(),n=function(e,t){if(!e)return;const o=e.toUpperCase().trim(),n={BYLAYER:"solid",BYBLOCK:"solid",CONTINUOUS:"solid",HIDDEN:"dash",DASHED:"dash",DASHEDX2:"dash",DASHED2:"dash",CENTER:"dash-dot",CENTERX2:"dash-dot",CENTER2:"dash-dot",DASHDOT:"dash-dot",DOTTED:"dot",DIVIDE:"short-dash",DIVIDEX2:"short-dash-dot",DIVIDE2:"short-dash-dot"};if(n[o])return n[o];if(t?.length){const e=Math.abs(t[0]??0),o=Math.abs(t[1]??0);if(2===t.length)return e<8&&o<6?"short-dash":e>=8&&e<=15&&o>=6&&o<=15?"dash":"long-dash";if(4===t.length)return e<6&&o<6?"short-dash-dot":e>=6&&e<=15&&o>=6&&o<=15?"dash-dot":"long-dash-dot"}return}(o,t?.pattern?.map((e=>parseFloat(e))));if(n)return n;const r=function(e){const t=e.toUpperCase();return t.includes("LONG")?"long-dash":t.includes("DOUBLE")?"long-dash-dot":t.includes("PHANTOM")?"dash-dot":void 0}(o);if(r)return r;const s=function(e){if(e?.pattern&&Array.isArray(e.pattern)){const t=e.pattern,o=t.some((e=>parseFloat(e)>.2)),n=t.some((e=>0===parseFloat(e)));return o&&!n?"dash":!o&&n?"dot":o&&n?"dash-dot":"solid"}return}(t);return s||"solid"}export class DxfEntityProcessor{dxfContext;entityHandlers;constructor(e,t,o={}){const r={dxf:{header:{},tables:{viewPort:{handle:"",ownerHandle:"",viewPorts:[]},lineType:{handle:"",ownerHandle:"",lineTypes:{}},layer:{handle:"",ownerHandle:"",layers:{}}},entities:[],blocks:{}},renderer_Object_Point:{},renderer_Object_Line:{},renderer_Object_Polygon:{},sourceSR:e,targetSR:102100===t.wkid?t:n.WebMercator,subLayers:[],pointFeatures:[],lineFeatures:[],polygonFeatures:[],textFeatures:[],async dxfEntities(){},convertToSpatialReference:async()=>[0,0],projectMany:async()=>[],intToRGB:f,colorIndex:0,...o};r.dxfToGeoJsonLineMapper=new DxfToGeoJsonLineMapper(r),r.dxfToGeoJsonPolygonMapper=new DxfToGeoJsonPolygonMapper(r),r.dxfToGeoJsonTextMapper=new DxfToGeoJsonTextMapper(r),r.dxfToGeoJsonInsertBlockMapper=new DxfToGeoJsonInsertBlockMapper(r),this.dxfContext=r,this.dxfContext.convertToSpatialReference=(e,t)=>this.convertToSpatialReference(e,t),this.dxfContext.projectMany=e=>this.projectMany(e),this.dxfContext.dxfEntities=async e=>this.process(e),this.entityHandlers={POINT:e=>this.dxfContext.dxfToGeoJsonInsertBlockMapper.processPoint(e),INSERT:e=>this.dxfContext.dxfToGeoJsonInsertBlockMapper.processInsert(e),LINE:async e=>{e.vertices?.length>=2&&await this.dxfContext.dxfToGeoJsonLineMapper.processLine(e)},ARC:async e=>{e.center&&void 0!==e.radius&&await this.dxfContext.dxfToGeoJsonLineMapper.processArc(e)},LWPOLYLINE:async e=>{Array.isArray(e.vertices)&&await this.dxfContext.dxfToGeoJsonLineMapper.processLWPolyline(e)},POLYLINE:async e=>{Array.isArray(e.vertices)&&await this.dxfContext.dxfToGeoJsonLineMapper.processPolyline(e)},SOLID:async e=>{e.points.length>=3&&await this.dxfContext.dxfToGeoJsonPolygonMapper.processSolid(e)},CIRCLE:async e=>{e.center&&e.radius&&await this.dxfContext.dxfToGeoJsonPolygonMapper.processCircle(e)},TEXT:e=>this.dxfContext.dxfToGeoJsonTextMapper.processText(e),MTEXT:async e=>{e.position&&await this.dxfContext.dxfToGeoJsonTextMapper.processMText(e)},ATTDEF:async e=>{e.startPoint&&await this.dxfContext.dxfToGeoJsonTextMapper.processAttDef(e)}}}getContext(){return this.dxfContext}async convertToSpatialReference(e,t){const n=new o({x:e,y:t,spatialReference:this.dxfContext.sourceSR}),[r]=await c([n],this.dxfContext.targetSR);return r?[r.longitude??0,r.latitude??0]:[0,0]}async projectMany(e){return(await c(e,this.dxfContext.targetSR)).map(((t,o)=>{const n=e[o];return[t?.longitude??n.x,t?.latitude??n.y]}))}async process(e){const t=Array.isArray(e)?e:[e];for(const e of t){if(!e||"BLOCK"===e.type||"ENDBLK"===e.type)continue;const t=this.entityHandlers[e.type];t&&await t(e)}}async processAll(){if(this.dxfContext.dxf.entities?.length>0){const e=50;for(let t=0;t<this.dxfContext.dxf.entities.length;t+=e){const o=this.dxfContext.dxf.entities.slice(t,t+e);await x(),await this.process(o)}}return await Promise.all([this.dxfContext.polygonFeatures.length>0&&this.dxfContext.dxfToGeoJsonPolygonMapper.polygonToGeoJSON(),this.dxfContext.lineFeatures.length>0&&this.dxfContext.dxfToGeoJsonLineMapper.lineToGeoJSON(),this.dxfContext.pointFeatures.length>0&&this.dxfContext.dxfToGeoJsonInsertBlockMapper.pointToGeoJSON(),this.dxfContext.textFeatures.length>0&&this.dxfContext.dxfToGeoJsonTextMapper.AnnotationToGeoJSON()].filter(Boolean)),this.dxfContext.subLayers}}
@@ -1 +1 @@
1
- window.navigationData = "data:application/octet-stream;base64,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"
1
+ window.navigationData = "data:application/octet-stream;base64,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"