@vertigis/arcgis-extensions 36.0.0 → 37.0.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/AppConfig.schema.json +4 -4
- package/data/Feature.js +1 -1
- package/data/FeatureList.js +1 -1
- package/data/FeatureSet.d.ts +57 -3
- package/data/FeatureSet.js +1 -1
- package/data/convert.js +1 -1
- package/docs/html/assets/search.js +1 -1
- package/docs/html/classes/data_Feature.Feature.html +12 -12
- package/docs/html/classes/data_FeatureSet.FeatureSet.html +30 -57
- package/docs/html/classes/data_FeatureStream.FeatureStream.html +1 -1
- package/docs/html/classes/support_Observable.Observable.html +1 -1
- package/docs/html/classes/utilities_ObservableMap.ObservableMap.html +18 -18
- package/docs/html/classes/utilities_ObservableSet.ObservableSet.html +1 -1
- package/docs/html/classes/utilities_ReadOnlyMap.ReadOnlyMap.html +14 -14
- package/docs/html/classes/utilities_asyncIterable.AsyncQueue.html +1 -1
- package/docs/html/interfaces/data_Feature.PresentableAttributes.html +14 -14
- package/docs/html/interfaces/data_FeatureSet.FeatureSetProperties.html +5 -5
- package/docs/html/interfaces/utilities_ObservableMap.MapChangeEvent.html +3 -3
- package/docs/html/modules/data_Feature.html +3 -3
- package/docs/html/modules/version.html +1 -1
- package/package.json +1 -1
- package/utilities/ObservableMap.d.ts +2 -0
- package/utilities/ObservableMap.js +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
package/AppConfig.schema.json
CHANGED
|
@@ -412,10 +412,10 @@
|
|
|
412
412
|
"items": {
|
|
413
413
|
"anyOf": [
|
|
414
414
|
{
|
|
415
|
-
"$ref": "#/definitions/
|
|
415
|
+
"$ref": "#/definitions/FeatureProperties"
|
|
416
416
|
},
|
|
417
417
|
{
|
|
418
|
-
"$ref": "#/definitions/
|
|
418
|
+
"$ref": "#/definitions/Feature"
|
|
419
419
|
}
|
|
420
420
|
]
|
|
421
421
|
},
|
|
@@ -550,10 +550,10 @@
|
|
|
550
550
|
"items": {
|
|
551
551
|
"anyOf": [
|
|
552
552
|
{
|
|
553
|
-
"$ref": "#/definitions/
|
|
553
|
+
"$ref": "#/definitions/FeatureProperties"
|
|
554
554
|
},
|
|
555
555
|
{
|
|
556
|
-
"$ref": "#/definitions/
|
|
556
|
+
"$ref": "#/definitions/Feature"
|
|
557
557
|
}
|
|
558
558
|
]
|
|
559
559
|
},
|
package/data/Feature.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{__decorate}from"tslib";import Graphic from"@arcgis/core/Graphic";import*as Arcade from"@arcgis/core/arcade/arcade";import{EntityBase}from"../Entity.js";import{Hyperlink}from"../Hyperlink.js";import{InvalidOperationError}from"../InvalidOperationError.js";import{ItemType}from"../ItemType.js";import{toEsriApiGeometry,toPortalGeometry}from"../portal/Geometry.js";import{serializable}from"../support/Serializable.js";import{MapTransformCollection}from"../utilities/MapTransformCollection.js";import{ObservableMap}from"../utilities/ObservableMap.js";import{ReadOnlyMap}from"../utilities/ReadOnlyMap.js";import{arcadeScriptUsesGeometry,isArcadeScriptAsync,runArcadeExpression,runAsyncArcadeExpression}from"../utilities/arcade.js";import{flatten,groupBy}from"../utilities/array.js";import{checkArg}from"../utilities/checkArg.js";import{Collection,compare}from"../utilities/collection.js";import{parse as parseDate,esriFormatToGeocortexFormat}from"../utilities/date.js";import{isCodedValueDomain}from"../utilities/esri.js";import{some,map as mapIterable,concat,forEach,find}from"../utilities/iterable.js";import{getLogger}from"../utilities/log.js";import{parse as parseNumber,NumberFormat}from"../utilities/number.js";import{map as promiseMap}from"../utilities/promise.js";import{format as formatString}from"../utilities/string.js";import{FeatureSettings}from"./FeatureSettings.js";import{_fieldWithArcadeXRegex,_fieldWithRelationshipRegex,Schema}from"./Schema.js";const log=getLogger("geocortex.api.data.Feature");export const SCORE_FIELD="_score";export const SCORE_FIELD_ORIGINAL="_score_original";let Feature=class extends EntityBase{constructor(e){super(e),this._itemType=ItemType.FEATURE,this._expressionFieldValues=new ObservableMap,this._expressionValuesUpdatePending=!1,this.settings=new FeatureSettings,this.settings._setFeature(this),this.schema=new Schema,this.schema._featureSettings=this.settings,this.attachments=new Collection,this.attributes=new ObservableMap,this._relatedFeatures=new ObservableMap,this.expressionFieldValues=new ExpressionFieldsValuesImpl(this._expressionFieldValues,this)}get geometry(){return this._geometry}set geometry(e){this._notifyChange("geometryType"),this._geometry=toEsriApiGeometry(e),this.schema.spatialReference=this._geometry?.spatialReference}get geometryType(){return this.geometry?this.geometry.type:void 0}get source(){return this._source}set source(e){this._source&&this.settings.parent===this._source.featureSettings&&(this.settings.parent=void 0),this._source&&this.schema.parent===this._source.schema&&(this.schema.parent=void 0),this._source=e,this.settings.parent||(this.settings.parent=e?e.featureSettings:void 0),this.schema.parent||(this.schema.parent=e?e.schema:void 0)}get primaryKey(){const e=this.attributes.get(this.schema.primaryKeyField);return null!=e?`${e}`:void 0}get hasGlobalId(){return!!this.schema.fields.find((e=>"global-id"===e.type))}get globalId(){const e=this.schema.fields.find((e=>"global-id"===e.type));return e?this.attributes.get(e.name):void 0}set globalId(e){const t=this.schema.fields.find((e=>"global-id"===e.type));if(!t)throw new InvalidOperationError("Cannot set global ID on feature -- no global ID field.");this.attributes.set(t.name,e)}get presentableAttributes(){return this._presentableAttributes=this._presentableAttributes||new PresentableAttributesImpl(this),this._presentableAttributes}get title(){return this.format(this._title||"")}get description(){return this.format(this._description)}get hyperlinks(){return this._hyperlinks||(this._hyperlinks=new HyperlinksCollection(this))}get relatedFeatures(){return this._relatedFeatures}get type(){if(this.schema.typeIdField&&this.attributes.has(this.schema.typeIdField)){const e=this.attributes.get(this.schema.typeIdField);return this.schema.types.find((t=>t.id===e))}}get _hydrationStatus(){return this._featureHydrationStatus?this._featureHydrationStatus:this.source?.capabilities?.supportsQuery&&1===this.attributes.size&&void 0!==this.primaryKey?"dehydrated":"hydrated"}set _hydrationStatus(e){this._featureHydrationStatus=e}get _title(){let e;return this.settings.popupTemplate&&(e="function"==typeof this.settings.popupTemplate.title?this.settings.popupTemplate.title():this.settings.popupTemplate.title),e||this.schema.displayField&&this.presentableAttributes.get(this.schema.displayField)||""}get _description(){if(this.settings.popupTemplate?.content){if("string"==typeof this.settings.popupTemplate.content)return this.settings.popupTemplate.content;if(Array.isArray(this.settings.popupTemplate.content)){const e=this.settings.popupTemplate.content.find((e=>"text"===e.type));if(e)return e.text}}return""}format(e,...t){let s="string"==typeof e?{format:e}:e;checkArg("options",s).isNotMissing();const{format:r}=s;checkArg("format",r).isNotMissing();let i=s.format.replace(escapedBraceRegex,escapedBracePlaceholder);return i=i.replace(fieldTokenRegex,((e,t,r,i,a)=>formatAttribute(this,t||r,i,{...s,format:a?`{0:${a}}`:"{0}"}))),i=i.replace(escapedBracePlaceholderRegex,"{{"),s={...s},s.format=i,formatString(s,...t)}clearExpressionInfos(){this._expressionFieldValues.clear()}async fetchExpressionInfos(e=!1){const{expressionInfos:t}=this.settings.popupTemplate??{};if(t)return await Promise.all(t.map((async e=>{try{const t=this.source?.layer??this.source?.sublayer;let s=this.source?.mapExtension;if(!s){const e=this.source?.layerExtension;s=e?.mapExtension}this._expressionFieldValues.set(e.name,await runAsyncArcadeExpression(e.expression,{layer:t,map:s?.map,feature:this,spatialReference:this.schema.spatialReference}))}catch(t){t instanceof Error&&log.error({message:"Error evaluating expression '{0}': {1}.",error:t},e.name,t.message),this._expressionFieldValues.set(e.name,invalidRelationshipOrExpression)}}))),e?this.attributes.on("change",(async e=>{this._expressionValuesUpdatePending||(this._expressionValuesUpdatePending=!0,setTimeout((async()=>{this._expressionValuesUpdatePending=!1,await this.fetchExpressionInfos()}),0))})):void 0}async fetchRelatedFeatures(e,t){if(!this.source)return;let s=[];if(e){const t=new Set(Array.isArray(e)?e:[e]);for(const e of t){const t="string"==typeof e?this.source.relationships.find((t=>t.id===e)):e;if(!t||!this.source.relationships.includes(t))throw new InvalidOperationError("Relationship not found in feature source.");s.push(t)}}else s=this.source.relationships.toArray();const r=await promiseMap(s,(async e=>[e,await e.getRelatedFeatures(this,t)]));for(const e of r)this._relatedFeatures.set(e[0],e[1])}async fetchAttachments(){if(this.source){const e=await this.source.getAttachments(this);compare(this.attachments,e,{equals:(e,t)=>e.id===t.id,onMissing:(e,t)=>this.attachments.remove(e),onNew:(e,t)=>this.attachments.add(e),onMatch:(e,t,s,r)=>{this.attachments.splice(s,1,t)}})}}async addAttachment(e){return this.source?.addAttachment(this,e)}async deleteAttachments(e){return this.source?.deleteAttachments(this,e)}_getSerializableProperties(){return{...super._getSerializableProperties(),attributes:{serializeModes:["project"],serialize:e=>{const t={};if("project"===e&&this.primaryKey&&this.source?.capabilities.supportsQuery)t[this.schema.primaryKeyField]=this.primaryKey;else for(const[e,s]of this.attributes.entries())t[e]=s;return t},deserialize:e=>{if(this.attributes.clear(),e instanceof Map)e.forEach(((e,t)=>{this.attributes.set(t,e)}));else for(const[t,s]of Object.entries(e))this.attributes.set(t,s)}},geometry:{serializeModes:["project"],serialize:e=>"project"===e&&this.source?.capabilities.supportsQuery?this.getDefault("geometry"):toPortalGeometry(this.geometry),deserialize:e=>this.geometry=toEsriApiGeometry(e)},settings:{serializeModes:["project"],serialize:e=>"project"===e&&this.source?.capabilities.supportsQuery?this.getDefault("settings"):this.settings.toJSON(e)},schema:{serializeModes:["project"],serialize:e=>"project"===e&&this.source?.capabilities.supportsQuery?this.getDefault("schema"):this.schema.toJSON(e)},source:["project"]}}_watchProperty(e,t,s,r){if("title"===e||"description"===e){const i=super._watchProperty(e,t,s,r),a="title"===e?"settings.popupTemplate.title":"settings.popupTemplate.content",o=this.watch(a,(()=>{this._notifyChange(e)})),n=this.presentableAttributes.on("change",(()=>{this._notifyChange(e)}));return{remove(){i.remove(),o.remove(),n.remove()}}}return super._watchProperty(e,t,s,r)}async _onInitialize(){const e=this._findRelationshipIds(this._title,this._description),t=this.source?this.source.relationships.map((e=>e.id)).toArray():[],s=[];for(const r of e)t.includes(r)?s.push(this.fetchRelatedFeatures(r)):log.error("Could not find relationship '{0}' referenced in feature title or description.",r);await Promise.all(s)}_findRelationshipIds(...e){const t=[];for(const s of e){let e;const r=s.replace(escapedBraceRegex,escapedBracePlaceholder);for(;e=relationshipIdRegex.exec(r),null!==e;){const s=e[0];t.includes(s)||t.push(e[1])}}return t}};Feature=__decorate([serializable],Feature);export{Feature};export function toFeature(e,t){const s=new Feature(t);if(e.attributes)for(const t of Object.keys(e.attributes))s.attributes.set(t,e.attributes[t]);return s.geometry=e.geometry,e.popupTemplate&&(s.settings.popupTemplate=e.popupTemplate),s}export function toGraphic(e){const t=new Graphic;t.attributes={};for(const s of e.attributes.keys())t.attributes[s]=e.attributes.get(s);return e.source?.layer&&(t.layer=e.source?.layer),t.geometry=e.geometry,e.settings.popupTemplate&&(t.popupTemplate=e.settings.popupTemplate),t}const ERR_PRESENTABLE_ATTRIBUTES_READONLY="Presentable attributes are read-only.",ERR_HYPERLINK_READONLY="Feature hyperlinks are read-only. Modify the feature's hyperlink templates instead.";class ExpressionFieldsValuesImpl extends ReadOnlyMap{constructor(e,t){super(e),this._feature=t}get(e){if(!super.has(e)){const{spatialReference:t}=this._feature.schema,s=this._feature.settings.popupTemplate?.expressionInfos?.find((t=>t.name===e));if(!s)return;(async()=>{try{if(isArcadeScriptAsync(s.expression,t)){const r=this._feature.source?.layer??this._feature.source?.sublayer;let i=this._feature.source?.mapExtension;if(!i){const e=this._feature.source?.layerExtension;i=e?.mapExtension}this._originalMap.set(e,await runAsyncArcadeExpression(s.expression,{feature:this._feature,layer:r,map:i?.map,spatialReference:t}))}else arcadeScriptUsesGeometry(s.expression,t)&&await Arcade.enableGeometrySupport(),this._originalMap.set(e,runArcadeExpression(s.expression,{feature:this._feature,spatialReference:t}))}catch(t){t instanceof Error&&log.error({message:"Error evaluating expression '{0}': {1}.",error:t},e,t.message),this._originalMap.set(e,invalidRelationshipOrExpression)}})()}return super.get(e)}}class PresentableAttributesImpl extends ReadOnlyMap{constructor(e){super(new ObservableMap),this._feature=e}get size(){return this._feature.attributes.size+this._feature.schema.fields._expressionFieldsLength}clear(){throw new InvalidOperationError(ERR_PRESENTABLE_ATTRIBUTES_READONLY)}delete(e){throw new InvalidOperationError(ERR_PRESENTABLE_ATTRIBUTES_READONLY)}forEach(e,t){checkArg("callback",e).isNotMissing();for(const s of this.keys())e.call(t,this.get(s),s,this)}get(e){const t=this._getFieldExtensionFormat(e);return this._formatAttribute(e,t)}has(e){return some(this.keys(),(t=>t===e))}set(...e){throw new InvalidOperationError(ERR_PRESENTABLE_ATTRIBUTES_READONLY)}*entries(){yield*mapIterable(this.keys(),(e=>[e,this.get(e)]))}*keys(){const e=this._feature.schema.fields.expressionFields.map((e=>e.name)),t=[];this._feature.source?.relationships&&this._feature.source.relationships.filter((e=>"one-to-one"===e.cardinality||"many-to-one"===e.cardinality)).forEach((e=>t.push(...e.relatedSource.schema.fields.map((t=>`relationships/${e.id}/${t.name}`)).toArray()))),yield*concat(this._feature.attributes.keys(),e.toArray(),t)}*values(){yield*mapIterable(this.keys(),(e=>this.get(e)))}[(Symbol.toStringTag,Symbol.iterator)](){return this.entries()}toJSON(){return Array.from(this.entries())}on(e,t){if(checkArg("callback",t).isNotMissing(),!this._numObservers){const e=new Map,t=new Set,s=()=>{t.forEach((e=>e.remove())),t.clear()},r=()=>{const t={added:Array.from(this.entries()).filter((t=>t[1]!==e.get(t[0]))),removed:Array.from(e.entries()).filter((e=>!this.has(e[0])||e[1]!==this.get(e[0]))),target:this};(t.added.length||t.removed.length)&&(this.emit("change",t),i())},i=()=>{e.clear(),s(),forEach(this.keys(),(s=>{const i=this._getFieldExtension(s);let a="{0}";if(i){const e=i.watch("format",(()=>{r()}));t.add(e),i.format&&(a=i.format)}e.set(s,this._formatAttribute(s,a))}))};i();const a=this._feature.attributes.on("change",(()=>{r()})),o=this._feature.schema.fieldExtensions.on("change",(()=>{r()})),n=this._feature.settings.formatSettings.watch(["numberFormat","dateFormat","locale"],(()=>{r()})),l=this._feature.expressionFieldValues.on("change",(()=>{r()})),p=this._feature.schema.fields.on("change",(e=>{(e.added?.some((e=>null!==e.name.match(_fieldWithArcadeXRegex)))||e.removed?.some((e=>null!==e.name.match(_fieldWithArcadeXRegex))))&&r()})),h=this._feature.settings.watch("popupTemplate",(()=>{r()}));this._onAllObserversRemoved=()=>{l.remove(),a.remove(),o.remove(),p.remove(),n.remove(),h.remove(),e.clear(),s()}}const s=super.on("change",t);return this._numObservers++,{remove:()=>{s.remove(),this._numObservers--,this._numObservers||this._onAllObserversRemoved()}}}watch(e,t){if("size"===e){const e=this._feature.attributes.watch("size",((e,s)=>{t(e+this._feature.schema.fields._expressionFieldsLength,s+this._feature.schema.fields._expressionFieldsLength,"size",this)})),s=this._feature.schema.fields.watch("_expressionFieldsLength",((e,s)=>{t(e+this._feature.attributes.size,s+this._feature.attributes.size,"size",this)}));return{remove:()=>{e.remove(),s.remove()}}}return super.watch(e,t)}_getFieldExtension(e){const t=this._feature.schema.findFieldByName(e);if(t)return this._feature.schema.fieldExtensions.forField(t)}_getFieldExtensionFormat(e){const t=this._getFieldExtension(e);return t?t.format:"{0}"}_formatAttribute(e,t){const s=e.match(_fieldWithArcadeXRegex),r=e.match(_fieldWithRelationshipRegex);if(s)return formatAttribute(this._feature,"expression",s[1],{format:t});if(r){const[,e,s]=r;return formatAttribute(this._feature,e,s,{format:t})}return formatAttribute(this._feature,void 0,e,{format:t})}}const fieldTokenRegex=/\{(?:relationships[\\/](\w\w*)[\\/])?(?:(expression)[\\/])?([a-zA-Z][.\w]*)(?::([^}]*))?\}/g,relationshipIdRegex=/\{relationships\/(\w\w*)[\\/]([^}]*)\}/g,escapedBraceRegex=/{{/g,escapedBracePlaceholder="\0MAGIC\0",escapedBracePlaceholderRegex=new RegExp(escapedBracePlaceholder,"g"),invalidRelationshipOrExpression="#INVALID";class HyperlinksCollection extends MapTransformCollection{constructor(e){super(e.settings.hyperlinkTemplates,(e=>this._getHyperlink(e))),this._feature=e}_getHyperlink(e){return this._hyperlinks=this._hyperlinks||new WeakMap,this._hyperlinks.has(e)||this._hyperlinks.set(e,new FeatureHyperlink(this._feature,e)),this._hyperlinks.get(e)}}let FeatureHyperlink=class extends Hyperlink{constructor(e,t){super(t.toJSON()),this._feature=e,this._template=t}get url(){return this._template.url?this._feature.format(this._template.url):this._template.url}set url(e){throw new InvalidOperationError(ERR_HYPERLINK_READONLY)}get text(){return this._template.text?this._feature.format(this._template.text):this._template.text}set text(e){throw new InvalidOperationError(ERR_HYPERLINK_READONLY)}get iconUrl(){return this._template.iconUrl?this._feature.format(this._template.iconUrl):this._template.iconUrl}set iconUrl(e){throw new InvalidOperationError(ERR_HYPERLINK_READONLY)}get target(){return this._template.target?this._feature.format(this._template.target):this._template.target}set target(e){throw new InvalidOperationError(ERR_HYPERLINK_READONLY)}get tooltip(){return this._template.tooltip?this._feature.format(this._template.tooltip):this._template.tooltip}set tooltip(e){throw new InvalidOperationError(ERR_HYPERLINK_READONLY)}_watchProperty(e,t,s,r){const i=super._watchProperty(e,t,s,r),a=this._template.watch(e,(()=>{this._notifyChange(e)})),o=this._feature.presentableAttributes.on("change",(()=>{this._notifyChange(e)}));return{remove:()=>{i.remove(),a.remove(),o.remove()}}}_getSerializableProperties(){return{}}};function formatAttribute(e,t,s,r={format:"{0}"}){if("expression"!==t){if(t){const i=find(e.relatedFeatures.keys(),(e=>e.id===t));if(!i)return log.debug("Could not resolve related field '{0}/{1}",t,s),invalidRelationshipOrExpression;const a=Array.from(e.relatedFeatures.get(i));return"many-to-one"===i.cardinality||"one-to-one"===i.cardinality?a.length<1?(log.debug("Could not resolve related field '{0}/{1}",t,s),invalidRelationshipOrExpression):formatAttributeValue(a[0],s,r):a.map((e=>formatAttributeValue(e,s,r))).filter((e=>""!==e)).join(",")}return formatAttributeValue(e,s,r)}if(!e.settings.popupTemplate?.expressionInfos?.find((e=>e.name===s)))return log.debug("Could not find expression '{0}'.",s),invalidRelationshipOrExpression;try{const t=e.expressionFieldValues.get(s)??r.defaultExpressionValue??"",i=e.schema.findFieldByName(`expression/${s}`);let a=r;if(i){const t=e.schema.fieldExtensions.forField(i);a=formatOptionsForField(e,s,formatOptionsFromSettings(t.formatSettings),a)}return formatValue(e,t,a)}catch(e){if(e instanceof Error)return log.error({message:"Error evaluating expression '{0}': {1}.",error:e},s,e.message),invalidRelationshipOrExpression;throw e}}function formatAttributeValue(e,t,s){let r=e.attributes.get(t);if(null==r)return"";const i=e.schema.findFieldByName(t);let a={format:"{0}"};const o=e.type?.domains?.[t];if(t===e.schema.typeIdField)r=e.type?e.type.name:r;else if(isCodedValueDomain(o)){const e=o.codedValues.find((e=>`${e.code}`==`${r.toString()}`));r=e?e.name:r}else if(i)if(isCodedValueDomain(i.domain)){const e=i.domain.codedValues.find((e=>`${e.code}`==`${r.toString()}`));e&&(r=e.name)}else{switch(i.type){case"integer":case"small-integer":case"single":case"double":r=parseNumber(r);break;case"date":r=parseDate({timeZone:e.schema.timeZone},r);break;default:r=`${r.toString()}`}a=formatOptionsFromSettings(e.schema.fieldExtensions.forField(i).formatSettings)}return formatValue(e,r,formatOptionsForField(e,t,a,s))}function formatValue(e,t,s){let r=s;if("number"==typeof t||t instanceof Date){r={...formatOptionsFromSettings(e.settings.formatSettings),...s}}return"{0}"===r.format&&"string"==typeof t?t:formatString(r,t)}function formatOptionsFromSettings(e){return{format:"{0}",dateFormat:e.dateFormat,numberFormat:e.numberFormat,currency:e.currency,fractionalDigits:e.fractionalDigits,locale:e.locale,timeZone:e.timeZone}}function formatOptionsForField(e,t,s,r){const{popupTemplate:i}=e.settings,a=i?.fieldInfos?i.fieldInfos.find((e=>e.fieldName===t)):void 0,o=a?a.format:void 0;let n;return o&&(n={format:"{0}",numberFormat:o.digitSeparator?NumberFormat.NUMBER:NumberFormat.FIXED_POINT,dateFormat:esriFormatToGeocortexFormat(o.dateFormat),fractionalDigits:o.places}),{...n,...s,...r}}FeatureHyperlink=__decorate([serializable],FeatureHyperlink);export async function resolveRelatedFeatures(e){const t=groupBy(e,(e=>e.source));await Promise.all(flatten([...t.keys()].map((e=>e.relationships.toArray()))).map((e=>(async e=>{[...(await e.getAllRelatedFeatures(t.get(e.source))).entries()].forEach((([t,s])=>{t.relatedFeatures.set(e,s)}))})(e))))}
|
|
1
|
+
import{__decorate}from"tslib";import Graphic from"@arcgis/core/Graphic";import*as Arcade from"@arcgis/core/arcade/arcade";import{EntityBase}from"../Entity.js";import{Hyperlink}from"../Hyperlink.js";import{InvalidOperationError}from"../InvalidOperationError.js";import{ItemType}from"../ItemType.js";import{toEsriApiGeometry,toPortalGeometry}from"../portal/Geometry.js";import{serializable}from"../support/Serializable.js";import{MapTransformCollection}from"../utilities/MapTransformCollection.js";import{ObservableMap}from"../utilities/ObservableMap.js";import{ReadOnlyMap}from"../utilities/ReadOnlyMap.js";import{arcadeScriptUsesGeometry,isArcadeScriptAsync,runArcadeExpression,runAsyncArcadeExpression}from"../utilities/arcade.js";import{flatten,groupBy}from"../utilities/array.js";import{checkArg}from"../utilities/checkArg.js";import{Collection,compare}from"../utilities/collection.js";import{parse as parseDate,esriFormatToGeocortexFormat}from"../utilities/date.js";import{isCodedValueDomain}from"../utilities/esri.js";import{some,map as mapIterable,concat,forEach,find}from"../utilities/iterable.js";import{getLogger}from"../utilities/log.js";import{parse as parseNumber,NumberFormat}from"../utilities/number.js";import{map as promiseMap}from"../utilities/promise.js";import{format as formatString}from"../utilities/string.js";import{FeatureSettings}from"./FeatureSettings.js";import{_fieldWithArcadeXRegex,_fieldWithRelationshipRegex,Schema}from"./Schema.js";const log=getLogger("geocortex.api.data.Feature");export const SCORE_FIELD="_score";export const SCORE_FIELD_ORIGINAL="_score_original";let Feature=class extends EntityBase{constructor(e){super(e),this._itemType=ItemType.FEATURE,this._expressionFieldValues=new ObservableMap,this._expressionValuesUpdatePending=!1,this.settings=new FeatureSettings,this.settings._setFeature(this),this.schema=new Schema,this.schema._featureSettings=this.settings,this.attachments=new Collection,this.attributes=new ObservableMap,this._relatedFeatures=new ObservableMap,this.expressionFieldValues=new ExpressionFieldsValuesImpl(this._expressionFieldValues,this)}get geometry(){return this._geometry}set geometry(e){this._notifyChange("geometryType"),this._geometry=toEsriApiGeometry(e),this.schema.spatialReference=this._geometry?.spatialReference}get geometryType(){return this.geometry?this.geometry.type:void 0}get source(){return this._source}set source(e){this._source&&this.settings.parent===this._source.featureSettings&&(this.settings.parent=void 0),this._source&&this.schema.parent===this._source.schema&&(this.schema.parent=void 0),this._source=e,this.settings.parent||(this.settings.parent=e?e.featureSettings:void 0),this.schema.parent||(this.schema.parent=e?e.schema:void 0)}get primaryKey(){const e=this.attributes.get(this.schema.primaryKeyField);return null!=e?`${e}`:void 0}get hasGlobalId(){return!!this.schema.fields.find((e=>"global-id"===e.type))}get globalId(){const e=this.schema.fields.find((e=>"global-id"===e.type));return e?this.attributes.get(e.name):void 0}set globalId(e){const t=this.schema.fields.find((e=>"global-id"===e.type));if(!t)throw new InvalidOperationError("Cannot set global ID on feature -- no global ID field.");this.attributes.set(t.name,e)}get presentableAttributes(){return this._presentableAttributes=this._presentableAttributes||new PresentableAttributesImpl(this),this._presentableAttributes}get title(){return this.format(this._title||"")}get description(){return this.format(this._description)}get hyperlinks(){return this._hyperlinks||(this._hyperlinks=new HyperlinksCollection(this))}get relatedFeatures(){return this._relatedFeatures}get type(){if(this.schema.typeIdField&&this.attributes.has(this.schema.typeIdField)){const e=this.attributes.get(this.schema.typeIdField);return this.schema.types.find((t=>t.id===e))}}get _hydrationStatus(){return this._featureHydrationStatus?this._featureHydrationStatus:this.source?.capabilities?.supportsQuery&&1===this.attributes.size&&void 0!==this.primaryKey?"dehydrated":"hydrated"}set _hydrationStatus(e){this._featureHydrationStatus=e}get _key(){return`${this.source?.id}//${this.primaryKey??this.globalId??this.id}`}get _title(){let e;return this.settings.popupTemplate&&(e="function"==typeof this.settings.popupTemplate.title?this.settings.popupTemplate.title():this.settings.popupTemplate.title),e||this.schema.displayField&&this.presentableAttributes.get(this.schema.displayField)||""}get _description(){if(this.settings.popupTemplate?.content){if("string"==typeof this.settings.popupTemplate.content)return this.settings.popupTemplate.content;if(Array.isArray(this.settings.popupTemplate.content)){const e=this.settings.popupTemplate.content.find((e=>"text"===e.type));if(e)return e.text}}return""}format(e,...t){let s="string"==typeof e?{format:e}:e;checkArg("options",s).isNotMissing();const{format:r}=s;checkArg("format",r).isNotMissing();let i=s.format.replace(escapedBraceRegex,escapedBracePlaceholder);return i=i.replace(fieldTokenRegex,((e,t,r,i,a)=>formatAttribute(this,t||r,i,{...s,format:a?`{0:${a}}`:"{0}"}))),i=i.replace(escapedBracePlaceholderRegex,"{{"),s={...s},s.format=i,formatString(s,...t)}clearExpressionInfos(){this._expressionFieldValues.clear()}async fetchExpressionInfos(e=!1){const{expressionInfos:t}=this.settings.popupTemplate??{};if(t)return await Promise.all(t.map((async e=>{try{const t=this.source?.layer??this.source?.sublayer;let s=this.source?.mapExtension;if(!s){const e=this.source?.layerExtension;s=e?.mapExtension}this._expressionFieldValues.set(e.name,await runAsyncArcadeExpression(e.expression,{layer:t,map:s?.map,feature:this,spatialReference:this.schema.spatialReference}))}catch(t){t instanceof Error&&log.error({message:"Error evaluating expression '{0}': {1}.",error:t},e.name,t.message),this._expressionFieldValues.set(e.name,invalidRelationshipOrExpression)}}))),e?this.attributes.on("change",(async e=>{this._expressionValuesUpdatePending||(this._expressionValuesUpdatePending=!0,setTimeout((async()=>{this._expressionValuesUpdatePending=!1,await this.fetchExpressionInfos()}),0))})):void 0}async fetchRelatedFeatures(e,t){if(!this.source)return;let s=[];if(e){const t=new Set(Array.isArray(e)?e:[e]);for(const e of t){const t="string"==typeof e?this.source.relationships.find((t=>t.id===e)):e;if(!t||!this.source.relationships.includes(t))throw new InvalidOperationError("Relationship not found in feature source.");s.push(t)}}else s=this.source.relationships.toArray();const r=await promiseMap(s,(async e=>[e,await e.getRelatedFeatures(this,t)]));for(const e of r)this._relatedFeatures.set(e[0],e[1])}async fetchAttachments(){if(this.source){const e=await this.source.getAttachments(this);compare(this.attachments,e,{equals:(e,t)=>e.id===t.id,onMissing:(e,t)=>this.attachments.remove(e),onNew:(e,t)=>this.attachments.add(e),onMatch:(e,t,s,r)=>{this.attachments.splice(s,1,t)}})}}async addAttachment(e){return this.source?.addAttachment(this,e)}async deleteAttachments(e){return this.source?.deleteAttachments(this,e)}_getSerializableProperties(){return{...super._getSerializableProperties(),attributes:{serializeModes:["project"],serialize:e=>{const t={};if("project"===e&&this.primaryKey&&this.source?.capabilities.supportsQuery)t[this.schema.primaryKeyField]=this.primaryKey;else for(const[e,s]of this.attributes.entries())t[e]=s;return t},deserialize:e=>{if(this.attributes.clear(),e instanceof Map)e.forEach(((e,t)=>{this.attributes.set(t,e)}));else for(const[t,s]of Object.entries(e))this.attributes.set(t,s)}},geometry:{serializeModes:["project"],serialize:e=>"project"===e&&this.source?.capabilities.supportsQuery?this.getDefault("geometry"):toPortalGeometry(this.geometry),deserialize:e=>this.geometry=toEsriApiGeometry(e)},settings:{serializeModes:["project"],serialize:e=>"project"===e&&this.source?.capabilities.supportsQuery?this.getDefault("settings"):this.settings.toJSON(e)},schema:{serializeModes:["project"],serialize:e=>"project"===e&&this.source?.capabilities.supportsQuery?this.getDefault("schema"):this.schema.toJSON(e)},source:["project"]}}_watchProperty(e,t,s,r){if("title"===e||"description"===e){const i=super._watchProperty(e,t,s,r),a="title"===e?"settings.popupTemplate.title":"settings.popupTemplate.content",o=this.watch(a,(()=>{this._notifyChange(e)})),n=this.presentableAttributes.on("change",(()=>{this._notifyChange(e)}));return{remove(){i.remove(),o.remove(),n.remove()}}}return super._watchProperty(e,t,s,r)}async _onInitialize(){const e=this._findRelationshipIds(this._title,this._description),t=this.source?this.source.relationships.map((e=>e.id)).toArray():[],s=[];for(const r of e)t.includes(r)?s.push(this.fetchRelatedFeatures(r)):log.error("Could not find relationship '{0}' referenced in feature title or description.",r);await Promise.all(s)}_findRelationshipIds(...e){const t=[];for(const s of e){let e;const r=s.replace(escapedBraceRegex,escapedBracePlaceholder);for(;e=relationshipIdRegex.exec(r),null!==e;){const s=e[0];t.includes(s)||t.push(e[1])}}return t}};Feature=__decorate([serializable],Feature);export{Feature};export function toFeature(e,t){const s=new Feature(t);if(e.attributes)for(const t of Object.keys(e.attributes))s.attributes.set(t,e.attributes[t]);return s.geometry=e.geometry,e.popupTemplate&&(s.settings.popupTemplate=e.popupTemplate),s}export function toGraphic(e){const t=new Graphic;t.attributes={};for(const s of e.attributes.keys())t.attributes[s]=e.attributes.get(s);return e.source?.layer&&(t.layer=e.source?.layer),t.geometry=e.geometry,e.settings.popupTemplate&&(t.popupTemplate=e.settings.popupTemplate),t}const ERR_PRESENTABLE_ATTRIBUTES_READONLY="Presentable attributes are read-only.",ERR_HYPERLINK_READONLY="Feature hyperlinks are read-only. Modify the feature's hyperlink templates instead.";class ExpressionFieldsValuesImpl extends ReadOnlyMap{constructor(e,t){super(e),this._feature=t}get(e){if(!super.has(e)){const{spatialReference:t}=this._feature.schema,s=this._feature.settings.popupTemplate?.expressionInfos?.find((t=>t.name===e));if(!s)return;(async()=>{try{if(isArcadeScriptAsync(s.expression,t)){const r=this._feature.source?.layer??this._feature.source?.sublayer;let i=this._feature.source?.mapExtension;if(!i){const e=this._feature.source?.layerExtension;i=e?.mapExtension}this._originalMap.set(e,await runAsyncArcadeExpression(s.expression,{feature:this._feature,layer:r,map:i?.map,spatialReference:t}))}else arcadeScriptUsesGeometry(s.expression,t)&&await Arcade.enableGeometrySupport(),this._originalMap.set(e,runArcadeExpression(s.expression,{feature:this._feature,spatialReference:t}))}catch(t){t instanceof Error&&log.error({message:"Error evaluating expression '{0}': {1}.",error:t},e,t.message),this._originalMap.set(e,invalidRelationshipOrExpression)}})()}return super.get(e)}}class PresentableAttributesImpl extends ReadOnlyMap{constructor(e){super(new ObservableMap),this._feature=e}get size(){return this._feature.attributes.size+this._feature.schema.fields._expressionFieldsLength}clear(){throw new InvalidOperationError(ERR_PRESENTABLE_ATTRIBUTES_READONLY)}delete(e){throw new InvalidOperationError(ERR_PRESENTABLE_ATTRIBUTES_READONLY)}forEach(e,t){checkArg("callback",e).isNotMissing();for(const s of this.keys())e.call(t,this.get(s),s,this)}get(e){const t=this._getFieldExtensionFormat(e);return this._formatAttribute(e,t)}has(e){return some(this.keys(),(t=>t===e))}set(...e){throw new InvalidOperationError(ERR_PRESENTABLE_ATTRIBUTES_READONLY)}*entries(){yield*mapIterable(this.keys(),(e=>[e,this.get(e)]))}*keys(){const e=this._feature.schema.fields.expressionFields.map((e=>e.name)),t=[];this._feature.source?.relationships&&this._feature.source.relationships.filter((e=>"one-to-one"===e.cardinality||"many-to-one"===e.cardinality)).forEach((e=>t.push(...e.relatedSource.schema.fields.map((t=>`relationships/${e.id}/${t.name}`)).toArray()))),yield*concat(this._feature.attributes.keys(),e.toArray(),t)}*values(){yield*mapIterable(this.keys(),(e=>this.get(e)))}[(Symbol.toStringTag,Symbol.iterator)](){return this.entries()}toJSON(){return Array.from(this.entries())}on(e,t){if(checkArg("callback",t).isNotMissing(),!this._numObservers){const e=new Map,t=new Set,s=()=>{t.forEach((e=>e.remove())),t.clear()},r=()=>{const t={added:Array.from(this.entries()).filter((t=>t[1]!==e.get(t[0]))),removed:Array.from(e.entries()).filter((e=>!this.has(e[0])||e[1]!==this.get(e[0]))),target:this};(t.added.length||t.removed.length)&&(this.emit("change",t),i())},i=()=>{e.clear(),s(),forEach(this.keys(),(s=>{const i=this._getFieldExtension(s);let a="{0}";if(i){const e=i.watch("format",(()=>{r()}));t.add(e),i.format&&(a=i.format)}e.set(s,this._formatAttribute(s,a))}))};i();const a=this._feature.attributes.on("change",(()=>{r()})),o=this._feature.schema.fieldExtensions.on("change",(()=>{r()})),n=this._feature.settings.formatSettings.watch(["numberFormat","dateFormat","locale"],(()=>{r()})),l=this._feature.expressionFieldValues.on("change",(()=>{r()})),p=this._feature.schema.fields.on("change",(e=>{(e.added?.some((e=>null!==e.name.match(_fieldWithArcadeXRegex)))||e.removed?.some((e=>null!==e.name.match(_fieldWithArcadeXRegex))))&&r()})),h=this._feature.settings.watch("popupTemplate",(()=>{r()}));this._onAllObserversRemoved=()=>{l.remove(),a.remove(),o.remove(),p.remove(),n.remove(),h.remove(),e.clear(),s()}}const s=super.on("change",t);return this._numObservers++,{remove:()=>{s.remove(),this._numObservers--,this._numObservers||this._onAllObserversRemoved()}}}watch(e,t){if("size"===e){const e=this._feature.attributes.watch("size",((e,s)=>{t(e+this._feature.schema.fields._expressionFieldsLength,s+this._feature.schema.fields._expressionFieldsLength,"size",this)})),s=this._feature.schema.fields.watch("_expressionFieldsLength",((e,s)=>{t(e+this._feature.attributes.size,s+this._feature.attributes.size,"size",this)}));return{remove:()=>{e.remove(),s.remove()}}}return super.watch(e,t)}_getFieldExtension(e){const t=this._feature.schema.findFieldByName(e);if(t)return this._feature.schema.fieldExtensions.forField(t)}_getFieldExtensionFormat(e){const t=this._getFieldExtension(e);return t?t.format:"{0}"}_formatAttribute(e,t){const s=e.match(_fieldWithArcadeXRegex),r=e.match(_fieldWithRelationshipRegex);if(s)return formatAttribute(this._feature,"expression",s[1],{format:t});if(r){const[,e,s]=r;return formatAttribute(this._feature,e,s,{format:t})}return formatAttribute(this._feature,void 0,e,{format:t})}}const fieldTokenRegex=/\{(?:relationships[\\/](\w\w*)[\\/])?(?:(expression)[\\/])?([a-zA-Z][.\w]*)(?::([^}]*))?\}/g,relationshipIdRegex=/\{relationships\/(\w\w*)[\\/]([^}]*)\}/g,escapedBraceRegex=/{{/g,escapedBracePlaceholder="\0MAGIC\0",escapedBracePlaceholderRegex=new RegExp(escapedBracePlaceholder,"g"),invalidRelationshipOrExpression="#INVALID";class HyperlinksCollection extends MapTransformCollection{constructor(e){super(e.settings.hyperlinkTemplates,(e=>this._getHyperlink(e))),this._feature=e}_getHyperlink(e){return this._hyperlinks=this._hyperlinks||new WeakMap,this._hyperlinks.has(e)||this._hyperlinks.set(e,new FeatureHyperlink(this._feature,e)),this._hyperlinks.get(e)}}let FeatureHyperlink=class extends Hyperlink{constructor(e,t){super(t.toJSON()),this._feature=e,this._template=t}get url(){return this._template.url?this._feature.format(this._template.url):this._template.url}set url(e){throw new InvalidOperationError(ERR_HYPERLINK_READONLY)}get text(){return this._template.text?this._feature.format(this._template.text):this._template.text}set text(e){throw new InvalidOperationError(ERR_HYPERLINK_READONLY)}get iconUrl(){return this._template.iconUrl?this._feature.format(this._template.iconUrl):this._template.iconUrl}set iconUrl(e){throw new InvalidOperationError(ERR_HYPERLINK_READONLY)}get target(){return this._template.target?this._feature.format(this._template.target):this._template.target}set target(e){throw new InvalidOperationError(ERR_HYPERLINK_READONLY)}get tooltip(){return this._template.tooltip?this._feature.format(this._template.tooltip):this._template.tooltip}set tooltip(e){throw new InvalidOperationError(ERR_HYPERLINK_READONLY)}_watchProperty(e,t,s,r){const i=super._watchProperty(e,t,s,r),a=this._template.watch(e,(()=>{this._notifyChange(e)})),o=this._feature.presentableAttributes.on("change",(()=>{this._notifyChange(e)}));return{remove:()=>{i.remove(),a.remove(),o.remove()}}}_getSerializableProperties(){return{}}};function formatAttribute(e,t,s,r={format:"{0}"}){if("expression"!==t){if(t){const i=find(e.relatedFeatures.keys(),(e=>e.id===t));if(!i)return log.debug("Could not resolve related field '{0}/{1}",t,s),invalidRelationshipOrExpression;const a=Array.from(e.relatedFeatures.get(i));return"many-to-one"===i.cardinality||"one-to-one"===i.cardinality?a.length<1?(log.debug("Could not resolve related field '{0}/{1}",t,s),invalidRelationshipOrExpression):formatAttributeValue(a[0],s,r):a.map((e=>formatAttributeValue(e,s,r))).filter((e=>""!==e)).join(",")}return formatAttributeValue(e,s,r)}if(!e.settings.popupTemplate?.expressionInfos?.find((e=>e.name===s)))return log.debug("Could not find expression '{0}'.",s),invalidRelationshipOrExpression;try{const t=e.expressionFieldValues.get(s)??r.defaultExpressionValue??"",i=e.schema.findFieldByName(`expression/${s}`);let a=r;if(i){const t=e.schema.fieldExtensions.forField(i);a=formatOptionsForField(e,s,formatOptionsFromSettings(t.formatSettings),a)}return formatValue(e,t,a)}catch(e){if(e instanceof Error)return log.error({message:"Error evaluating expression '{0}': {1}.",error:e},s,e.message),invalidRelationshipOrExpression;throw e}}function formatAttributeValue(e,t,s){let r=e.attributes.get(t);if(null==r)return"";const i=e.schema.findFieldByName(t);let a={format:"{0}"};const o=e.type?.domains?.[t];if(t===e.schema.typeIdField)r=e.type?e.type.name:r;else if(isCodedValueDomain(o)){const e=o.codedValues.find((e=>`${e.code}`==`${r.toString()}`));r=e?e.name:r}else if(i)if(isCodedValueDomain(i.domain)){const e=i.domain.codedValues.find((e=>`${e.code}`==`${r.toString()}`));e&&(r=e.name)}else{switch(i.type){case"integer":case"small-integer":case"single":case"double":r=parseNumber(r);break;case"date":r=parseDate({timeZone:e.schema.timeZone},r);break;default:r=`${r.toString()}`}a=formatOptionsFromSettings(e.schema.fieldExtensions.forField(i).formatSettings)}return formatValue(e,r,formatOptionsForField(e,t,a,s))}function formatValue(e,t,s){let r=s;if("number"==typeof t||t instanceof Date){r={...formatOptionsFromSettings(e.settings.formatSettings),...s}}return"{0}"===r.format&&"string"==typeof t?t:formatString(r,t)}function formatOptionsFromSettings(e){return{format:"{0}",dateFormat:e.dateFormat,numberFormat:e.numberFormat,currency:e.currency,fractionalDigits:e.fractionalDigits,locale:e.locale,timeZone:e.timeZone}}function formatOptionsForField(e,t,s,r){const{popupTemplate:i}=e.settings,a=i?.fieldInfos?i.fieldInfos.find((e=>e.fieldName===t)):void 0,o=a?a.format:void 0;let n;return o&&(n={format:"{0}",numberFormat:o.digitSeparator?NumberFormat.NUMBER:NumberFormat.FIXED_POINT,dateFormat:esriFormatToGeocortexFormat(o.dateFormat),fractionalDigits:o.places}),{...n,...s,...r}}FeatureHyperlink=__decorate([serializable],FeatureHyperlink);export async function resolveRelatedFeatures(e){const t=groupBy(e,(e=>e.source));await Promise.all(flatten([...t.keys()].map((e=>e.relationships.toArray()))).map((e=>(async e=>{[...(await e.getAllRelatedFeatures(t.get(e.source))).entries()].forEach((([t,s])=>{t.relatedFeatures.set(e,s)}))})(e))))}
|
package/data/FeatureList.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{__decorate}from"tslib";import Field from"@arcgis/core/layers/support/Field";import{ArgumentError}from"../ArgumentError.js";import{generateId}from"../Entity.js";import{isFeatureSet,ItemType}from"../ItemType.js";import{assignProperties,filterJSONProperties,getDefaults,getSerializableProperties,serializable}from"../support/Serializable.js";import{getSearchableValue}from"../tasks/search/_utilities.js";import{ReadOnlyCollection}from"../utilities/ReadOnlyCollection.js";import{Collection}from"../utilities/collection.js";import{parse as parseDate}from"../utilities/date.js";import{isCodedValueDomain}from"../utilities/esri.js";import{parse as parseNumber}from"../utilities/number.js";import{escapeRegExp}from"../utilities/string.js";import{FeatureSet}from"./FeatureSet.js";let FeatureList=class extends ReadOnlyCollection{constructor(e){if(super(new Collection),this.id=e?.id??generateId(),isFeatureSet(e))this.featureSet=e;else if(e){const t=e;Array.isArray(t.featureSet)?this.featureSet=new FeatureSet({features:t.featureSet}):isFeatureSet(t.featureSet)?this.featureSet=t.featureSet:this.featureSet=new FeatureSet(t.featureSet)}else this.featureSet=new FeatureSet;for(const e of this.featureSet)this._collection.add(e);this.featureSet.on("change",(e=>this._onFeatureSetChange(e)))}get itemType(){return ItemType.FEATURE_LIST}toItemUri(){return`item://${encodeURIComponent(ItemType.FEATURE_LIST)}/${encodeURIComponent(this.id)}`}assignProperties(e){assignProperties(this._getSerializableProperties(),this,e)}toJSON(e="all"){return filterJSONProperties(this._getSerializableProperties(),this,e)}getDefaults(){return getDefaults(this._getSerializableProperties())}getDefault(e){return this.getDefaults()[e]}sort(e){if("function"==typeof e)this._sortFunc=e;else if(Array.isArray(e))this._sortFunc=this._createSortFunc(e);else if("object"==typeof e&&e.field)this._sortFunc=this._createSortFunc([e]);else{if("string"!=typeof e)throw new ArgumentError("criteria","Invalid sort criteria.");this._sortFunc=this._createSortFunc([{field:e}])}this._sortFunc=this._stabilizeSortFunc(this._sortFunc),this._sort(this._sortFunc),this.emit("change",{moved:this._collection.toArray(),target:this})}applyFilter(e){if(e)if("function"==typeof e)this._filterFunc=e;else if(Array.isArray(e))this._filterFunc=this._createFilterFunc(e);else if("object"==typeof e&&e.field)this._filterFunc=this._createFilterFunc([e]);else{if("string"!=typeof e)throw new ArgumentError("criteria","Invalid filter criteria.");{const t=this.featureSet.schema.fieldExtensions.initializedItems.filter((e=>e.searchable)).map((t=>({field:t.field.name,match:e}))).toArray();this._filterFunc=this._createFilterFunc(t)}}else delete this._filterFunc;const t=new Set,i=[],r=[];let s=0;for(;s<this._collection.length;){const e=this._collection.getItemAt(s);this._filterFunc&&!this._filterFunc(e)?(i.push(e),this._collection.removeAt(s)):(t.add(e),s++)}for(const e of this.featureSet)t.has(e)||this._filterFunc&&!this._filterFunc(e)||(this._collection.add(e),r.push(e));this._sortFunc&&r.length&&(r.length<=10?this._insertionSort(this._sortFunc):this._sort(this._sortFunc)),(r.length||i.length)&&this.emit("change",{added:r,removed:i,target:this})}removeFilter(){this.applyFilter(void 0)}getSerializableProperties(e="all"){return getSerializableProperties(this._getSerializableProperties(),e)}_getSerializableProperties(){return{featureSet:{serializeModes:["project"],deserialize:e=>{isFeatureSet(e)?this.featureSet.assignProperties({title:e.title,features:[...e]}):Array.isArray(e)?this.featureSet.assignProperties({features:e}):this.featureSet.assignProperties(e)}}
|
|
1
|
+
import{__decorate}from"tslib";import Field from"@arcgis/core/layers/support/Field";import{ArgumentError}from"../ArgumentError.js";import{generateId}from"../Entity.js";import{isFeatureSet,ItemType}from"../ItemType.js";import{assignProperties,filterJSONProperties,getDefaults,getSerializableProperties,serializable}from"../support/Serializable.js";import{getSearchableValue}from"../tasks/search/_utilities.js";import{ReadOnlyCollection}from"../utilities/ReadOnlyCollection.js";import{Collection}from"../utilities/collection.js";import{parse as parseDate}from"../utilities/date.js";import{isCodedValueDomain}from"../utilities/esri.js";import{parse as parseNumber}from"../utilities/number.js";import{escapeRegExp}from"../utilities/string.js";import{FeatureSet}from"./FeatureSet.js";let FeatureList=class extends ReadOnlyCollection{constructor(e){if(super(new Collection),this.id=e?.id??generateId(),isFeatureSet(e))this.featureSet=e;else if(e){const t=e;Array.isArray(t.featureSet)?this.featureSet=new FeatureSet({features:t.featureSet}):isFeatureSet(t.featureSet)?this.featureSet=t.featureSet:this.featureSet=new FeatureSet(t.featureSet)}else this.featureSet=new FeatureSet;for(const e of this.featureSet)this._collection.add(e);this.featureSet.on("change",(e=>this._onFeatureSetChange(e)))}get itemType(){return ItemType.FEATURE_LIST}toItemUri(){return`item://${encodeURIComponent(ItemType.FEATURE_LIST)}/${encodeURIComponent(this.id)}`}assignProperties(e){assignProperties(this._getSerializableProperties(),this,e)}toJSON(e="all"){return filterJSONProperties(this._getSerializableProperties(),this,e)}getDefaults(){return getDefaults(this._getSerializableProperties())}getDefault(e){return this.getDefaults()[e]}sort(e){if("function"==typeof e)this._sortFunc=e;else if(Array.isArray(e))this._sortFunc=this._createSortFunc(e);else if("object"==typeof e&&e.field)this._sortFunc=this._createSortFunc([e]);else{if("string"!=typeof e)throw new ArgumentError("criteria","Invalid sort criteria.");this._sortFunc=this._createSortFunc([{field:e}])}this._sortFunc=this._stabilizeSortFunc(this._sortFunc),this._sort(this._sortFunc),this.emit("change",{moved:this._collection.toArray(),target:this})}applyFilter(e){if(e)if("function"==typeof e)this._filterFunc=e;else if(Array.isArray(e))this._filterFunc=this._createFilterFunc(e);else if("object"==typeof e&&e.field)this._filterFunc=this._createFilterFunc([e]);else{if("string"!=typeof e)throw new ArgumentError("criteria","Invalid filter criteria.");{const t=this.featureSet.schema.fieldExtensions.initializedItems.filter((e=>e.searchable)).map((t=>({field:t.field.name,match:e}))).toArray();this._filterFunc=this._createFilterFunc(t)}}else delete this._filterFunc;const t=new Set,i=[],r=[];let s=0;for(;s<this._collection.length;){const e=this._collection.getItemAt(s);this._filterFunc&&!this._filterFunc(e)?(i.push(e),this._collection.removeAt(s)):(t.add(e),s++)}for(const e of this.featureSet)t.has(e)||this._filterFunc&&!this._filterFunc(e)||(this._collection.add(e),r.push(e));this._sortFunc&&r.length&&(r.length<=10?this._insertionSort(this._sortFunc):this._sort(this._sortFunc)),(r.length||i.length)&&this.emit("change",{added:r,removed:i,target:this})}removeFilter(){this.applyFilter(void 0)}getSerializableProperties(e="all"){return getSerializableProperties(this._getSerializableProperties(),e)}_getSerializableProperties(){return{title:["project"],featureSet:{serializeModes:["project"],deserialize:e=>{isFeatureSet(e)?this.featureSet.assignProperties({title:e.title,features:[...e]}):Array.isArray(e)?this.featureSet.assignProperties({features:e}):this.featureSet.assignProperties(e)}}}}_onFeatureSetChange(e){if(e.removed?.length&&this._collection.removeMany(e.removed),e.added?.length){const t=this._filterFunc?e.added.filter(this._filterFunc):e.added;t.length&&(this._collection.addMany(t),this._sortFunc&&(t.length<=10?this._insertionSort(this._sortFunc):this._sort(this._sortFunc)))}}_createSortFunc(e){return(t,i)=>{for(let r of e){if("string"==typeof r&&(r={field:r}),!r.field)throw new ArgumentError("criteria","Invalid sort criteria.");const e=this._getField(r.field),s=this._getSortValue(t,e),o=this._getSortValue(i,e);let a="string"==typeof s?s.localeCompare(o):s-o;if("desc"===r.direction&&(a*=-1),0!==a)return a}return 0}}_stabilizeSortFunc(e){return(t,i)=>{const r=e(t,i);return 0===r?this._collection.indexOf(t)-this._collection.indexOf(i):r}}_createFilterFunc(e){const t=new Map;for(const i of e){if(!i.field)throw new ArgumentError("criteria","Invalid sort criteria.");if(!i.match)continue;const e=this._getField(i.field),r=this._getFilterRegex(i.match,e);t.set(e.name,r)}return t.size?e=>{for(const i of t.keys()){const r=this._getField(i),s=getSearchableValue(e,r),o=t.get(i);let a=o[0];if(o.length>1&&"string"!==r.type&&isCodedValueDomain(e.type?.domains?.[r.name])&&(a=o[1]),a.exec(s))return!0}return!1}:()=>!0}_getSortValue(e,t){if(isCodedValueDomain(e.type?.domains?.[t.name])||isCodedValueDomain(t.domain))return e.presentableAttributes.get(t.name);switch(t.type){case"integer":case"small-integer":case"double":case"single":case"oid":{const i=e.attributes.get(t.name);return null==i||isNaN(i)?Number.MIN_VALUE:parseNumber(i)}case"date":{const i=parseDate(e.attributes.get(t.name)).getTime();return isNaN(i)?0:i}default:return e.presentableAttributes.get(t.name)??""}}_getFilterRegex(e,t){if(t.domain&&"coded-value"===t.domain.type)return[new RegExp(`${escapeRegExp(e)}`,"i")];switch(t.type){case"integer":case"small-integer":case"double":case"single":case"oid":{const i=new RegExp(`(^|${SEPARATOR})${escapeRegExp(e)}`,"i");return this.featureSet.schema.types.some((e=>isCodedValueDomain(e.domains?.[t.name])))?[i,new RegExp(`${escapeRegExp(e)}`,"i")]:[i]}default:return[new RegExp(`${escapeRegExp(e)}`,"i")]}}_getField(e){let t=this.featureSet.schema.findFieldByName(e);return t||(t=new Field({name:e,type:this._inferFieldType(e),editable:!1}),this.featureSet.schema.fields.add(t)),t}_inferFieldType(e){for(const t of this.featureSet.values()){const i=t.attributes.get(e);if(null!=i)return"number"==typeof i?"double":i instanceof Date?"date":"string"}return"string"}_sort(e){this._collection._items.sort(e)}_insertionSort(e){const t=this._collection._items;for(let i=1;i<this.length;i++){const r=t[i];let s=i-1;for(;s>=0&&e(t[s],r)>0;)t[s+1]=t[s],s--;t[s+1]=r}}};FeatureList=__decorate([serializable],FeatureList);export{FeatureList};const SEPARATOR="\t";
|
package/data/FeatureSet.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Entity, EntityProperties } from "../Entity.js";
|
|
2
|
+
import { Observable } from "../support/Observable.js";
|
|
2
3
|
import { PropertyDefs, Serializable, SerializeMode } from "../support/Serializable.js";
|
|
3
|
-
import {
|
|
4
|
-
import type { ChangeEvent } from "../utilities/collection.js";
|
|
4
|
+
import type { ChangeEvent } from "../support/esri.js";
|
|
5
5
|
import { Feature, FeatureProperties } from "./Feature.js";
|
|
6
6
|
import { FeatureSettings, FeatureSettingsProperties } from "./FeatureSettings.js";
|
|
7
7
|
import type { FeatureSource } from "./FeatureSource.js";
|
|
@@ -34,7 +34,11 @@ export interface FeatureSetProperties extends EntityProperties {
|
|
|
34
34
|
/**
|
|
35
35
|
* A set of features that share a common schema.
|
|
36
36
|
*/
|
|
37
|
-
export declare class FeatureSet extends
|
|
37
|
+
export declare class FeatureSet extends Observable implements Entity, Serializable<FeatureSetProperties>, Set<Feature> {
|
|
38
|
+
/**
|
|
39
|
+
* Used by Object.toString().
|
|
40
|
+
*/
|
|
41
|
+
readonly [Symbol.toStringTag]: "Set";
|
|
38
42
|
/**
|
|
39
43
|
* @inheritdoc
|
|
40
44
|
*/
|
|
@@ -43,6 +47,10 @@ export declare class FeatureSet extends ObservableSet<Feature> implements Entity
|
|
|
43
47
|
* A human-readable name for the feature set.
|
|
44
48
|
*/
|
|
45
49
|
title: string;
|
|
50
|
+
/**
|
|
51
|
+
* The number of elements in the set.
|
|
52
|
+
*/
|
|
53
|
+
get size(): number;
|
|
46
54
|
/**
|
|
47
55
|
* The source for the features.
|
|
48
56
|
*/
|
|
@@ -63,6 +71,7 @@ export declare class FeatureSet extends ObservableSet<Feature> implements Entity
|
|
|
63
71
|
private _source;
|
|
64
72
|
private _rehydratingFeatureCount;
|
|
65
73
|
private readonly _rehydratingFeatures;
|
|
74
|
+
private readonly _features;
|
|
66
75
|
constructor(properties?: FeatureSetProperties);
|
|
67
76
|
/**
|
|
68
77
|
* Reads a stream of features into a {@link FeatureSet}.
|
|
@@ -80,6 +89,24 @@ export declare class FeatureSet extends ObservableSet<Feature> implements Entity
|
|
|
80
89
|
* @param properties An object containing property values to set.
|
|
81
90
|
*/
|
|
82
91
|
assignProperties(properties: FeatureSetProperties): void;
|
|
92
|
+
/**
|
|
93
|
+
* Indicates whether or not the set contains the specified element.
|
|
94
|
+
*
|
|
95
|
+
* @param feature The element to test for.
|
|
96
|
+
*/
|
|
97
|
+
has(feature: Feature): boolean;
|
|
98
|
+
/**
|
|
99
|
+
* @inheritdoc
|
|
100
|
+
*/
|
|
101
|
+
entries(): IterableIterator<[Feature, Feature]>;
|
|
102
|
+
/**
|
|
103
|
+
* @inheritdoc
|
|
104
|
+
*/
|
|
105
|
+
keys(): IterableIterator<Feature>;
|
|
106
|
+
/**
|
|
107
|
+
* @inheritdoc
|
|
108
|
+
*/
|
|
109
|
+
values(): IterableIterator<Feature>;
|
|
83
110
|
/**
|
|
84
111
|
* Returns a serializable representation of the feature set.
|
|
85
112
|
*
|
|
@@ -95,10 +122,28 @@ export declare class FeatureSet extends ObservableSet<Feature> implements Entity
|
|
|
95
122
|
* @inheritdoc
|
|
96
123
|
*/
|
|
97
124
|
add(feature: Feature): this;
|
|
125
|
+
/**
|
|
126
|
+
* @inheritdoc
|
|
127
|
+
*/
|
|
128
|
+
addMany(features: Iterable<Feature>): this;
|
|
129
|
+
/**
|
|
130
|
+
* @inheritdoc
|
|
131
|
+
*/
|
|
132
|
+
clear(): void;
|
|
98
133
|
/**
|
|
99
134
|
* @inheritdoc
|
|
100
135
|
*/
|
|
101
136
|
delete(feature: Feature): boolean;
|
|
137
|
+
/**
|
|
138
|
+
* @inheritdoc
|
|
139
|
+
*/
|
|
140
|
+
deleteMany(features: Iterable<Feature>): boolean;
|
|
141
|
+
/**
|
|
142
|
+
* @param callbackfn Function to execute for each element.
|
|
143
|
+
* @param thisArg Value to use as `this` when executing callback.
|
|
144
|
+
* @inheritdoc
|
|
145
|
+
*/
|
|
146
|
+
forEach(callbackfn: (value: Feature, value2: Feature, set: Set<Feature>) => void, thisArg?: unknown): void;
|
|
102
147
|
/**
|
|
103
148
|
* Finds a feature in the set with the given ID, or undefined if there is no match.
|
|
104
149
|
*
|
|
@@ -129,6 +174,15 @@ export declare class FeatureSet extends ObservableSet<Feature> implements Entity
|
|
|
129
174
|
* @param key The property of the object for which to get the default value.
|
|
130
175
|
*/
|
|
131
176
|
getDefault<T = unknown>(key: string): T;
|
|
177
|
+
/**
|
|
178
|
+
* Returns each element in the set in insertion order.
|
|
179
|
+
*/
|
|
180
|
+
[Symbol.iterator](): IterableIterator<Feature>;
|
|
181
|
+
protected _add(feature: Feature, notify?: boolean): this;
|
|
182
|
+
/**
|
|
183
|
+
* @inheritdoc
|
|
184
|
+
*/
|
|
185
|
+
protected _delete(feature: Feature, notify?: boolean): boolean;
|
|
132
186
|
/**
|
|
133
187
|
* @inheritdoc
|
|
134
188
|
*/
|
package/data/FeatureSet.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var FeatureSet_1;import{__decorate}from"tslib";import Collection from"@arcgis/core/core/Collection";import{generateId}from"../Entity.js";import{isFeature,ItemType}from"../ItemType.js";import{assignProperties,filterJSONProperties,getDefaults,getSerializableProperties,serializable}from"../support/Serializable.js";import{
|
|
1
|
+
var FeatureSet_1;import{__decorate}from"tslib";import Collection from"@arcgis/core/core/Collection";import{generateId}from"../Entity.js";import{isFeature,ItemType}from"../ItemType.js";import{Observable}from"../support/Observable.js";import{assignProperties,filterJSONProperties,getDefaults,getSerializableProperties,serializable}from"../support/Serializable.js";import{ObservableMap}from"../utilities/ObservableMap.js";import{groupBy}from"../utilities/array.js";import{toArray,from,empty}from"../utilities/asyncIterable.js";import{compare,find}from"../utilities/iterable.js";import{getLogger}from"../utilities/log.js";import{watchEach}from"../utilities/watch.js";import{Feature}from"./Feature.js";import{FeatureSettings}from"./FeatureSettings.js";import{Schema}from"./Schema.js";const log=getLogger("feature-set");let FeatureSet=FeatureSet_1=class extends Observable{constructor(e){super(),this.settings=new FeatureSettings,this.schema=new Schema,this._rehydratingFeatureCount=0,this._rehydratingFeatures=new Collection,this._features=new ObservableMap,this.schema._featureSettings=this.settings,this.id=e?.id??generateId(),watchEach(this._rehydratingFeatures,"_featureHydrationStatus",((e,t,r,s)=>{if(this._rehydratingFeatureCount--,!this._rehydratingFeatureCount){const e=this._rehydratingFeatures.toArray();this.addMany(e),this.emit("feature-hydration-complete",e)}})),this.on("dehydrated-features-added",(async e=>{this._rehydratingFeatures.addMany(e);const t=groupBy(e,(e=>e.source)),r=groupBy(await toArray(from([...t.entries()].map((([e,t])=>{let r;try{r=e?.getFeatures(t.map((e=>e.primaryKey)).filter((e=>!!e)))??empty()}catch(t){r=empty(),log.error({error:t,message:`Failed to hydrate features from source '${e?.title??e?.id}`})}return r})))),(e=>e.source));[...t.entries()].forEach((([e,t])=>{const s=r.get(e);t.forEach((e=>{const t=s?.find((t=>t.primaryKey===e.primaryKey));t&&(e.geometry=t.geometry,[...t.attributes.entries()].forEach((([t,r])=>{e.attributes.set(t,r)}))),e._hydrationStatus=void 0}))}))})),this.assignProperties(e)}get size(){return this._features.size}get source(){return this._source}set source(e){this._source&&this.settings.parent===this._source.featureSettings&&(this.settings.parent=void 0),this._source&&this.schema.parent===this._source.schema&&(this.settings.parent=void 0),this._source=e,this.settings.parent||(this.settings.parent=e?e.featureSettings:void 0),this.schema.parent||(this.schema.parent=e?e.schema:void 0)}get itemType(){return ItemType.FEATURE_SET}static async fromFeatureStream(e,t){const r=new FeatureSet_1(t);for await(const t of e)r.add(t);return r}on(e,t){return super.on(e,t)}assignProperties(e){assignProperties(this._getSerializableProperties(),this,e)}has(e){return this._features.has(e._key)}entries(){return[...this._features].map((([e,t])=>[t,t]))[Symbol.iterator]()}keys(){return this._features.values()}values(){return this._features.values()}toJSON(e="all"){return filterJSONProperties(this._getSerializableProperties(),this,e)}toItemUri(){return`item://${encodeURIComponent(ItemType.FEATURE_SET)}/${encodeURIComponent(this.id)}`}add(e){return this._add(e)}addMany(e){const t=[],r=[];for(const s of e){const e=this._features.get(s._key);s!==e&&(this._add(s,!1),t.push(s),e&&r.push(e))}return t.length&&(this._notifyChange("size"),this.emit("change",{added:t,removed:r,moved:[],target:this})),this}clear(){const e=Array.from(this.values());this._features.clear(),this._notifyChange("size"),this.emit("change",{added:[],removed:e,moved:[],target:this})}delete(e){return this._delete(e)}deleteMany(e){const t=[];for(const r of e){const e=this._features.get(r._key);this._delete(r,!1)&&t.push(e)}return t.length&&(this._notifyChange("size"),this.emit("change",{added:[],removed:t,moved:[],target:this})),!!t.length}forEach(e,t){this._features.forEach((t=>e(t,t,this)),t)}findById(e){return find(this,(t=>t.id===e))}findByPrimaryKey(e){return find(this,(t=>t.primaryKey===e))}getSerializableProperties(e="all"){return getSerializableProperties(this._getSerializableProperties(),e)}getDefaults(){return getDefaults(this._getSerializableProperties())}getDefault(e){return this.getDefaults()[e]}[(Symbol.toStringTag,Symbol.iterator)](){return this._features.values()[Symbol.iterator]()}_add(e,t=!0){const r=this._features.get(e._key);return r&&r!==e&&this._delete(r,!1),this._features.set(e._key,e),t&&r!==e&&(this._notifyChange("size"),this.emit("change",{added:[e],removed:r?[r]:[],moved:[],target:this})),this.source&&!e.source&&(e.source=this.source),e.schema.parent||(e.schema.parent=this.schema),e.settings.parent||(e.settings.parent=this.settings),this}_delete(e,t=!0){if(!this.has(e))return!1;const r=this._features.get(e._key);return this._features.delete(e._key),t&&(this._notifyChange("size"),this.emit("change",{added:[],removed:[r],moved:[],target:this})),e.schema.parent===this.schema&&(e.schema.parent=void 0),e.settings.parent===this.settings&&(e.settings.parent=void 0),!0}_getSerializableProperties(){return{id:["project"],features:{serializeModes:["project"],serialize:()=>[...this],deserialize:e=>{const t=[],r=[];compare(this._rehydratingFeatures.concat([...this]),e,{onNew:e=>{if(isFeature(e))"dehydrated"===e._hydrationStatus?(e._hydrationStatus="rehydrating",this._rehydratingFeatureCount++,t.push(e)):"rehydrating"===e._hydrationStatus?(this._rehydratingFeatureCount++,this._rehydratingFeatures.push(e)):(r.push(e),this.add(e));else{const t=new Feature(e);r.push(t),this.add(t)}},onMatch:(e,r)=>{isFeature(r)?"dehydrated"===e._hydrationStatus?(e._hydrationStatus="rehydrating",this._rehydratingFeatureCount++,t.push(e)):e!==r&&this.add(r):e.assignProperties(r)},onMissing:e=>{this.delete(e)},equals:(e,t)=>isFeature(t)?e._key===t._key:e.id===t.id}),t.length?this.emit("dehydrated-features-added",t):this._rehydratingFeatureCount||this.emit("feature-hydration-complete",r)}},title:["project"],source:[],schema:[],settings:[]}}};FeatureSet=FeatureSet_1=__decorate([serializable],FeatureSet);export{FeatureSet};
|
package/data/convert.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import Point from"@arcgis/core/geometry/Point";import SpatialReference from"@arcgis/core/geometry/SpatialReference";import{translate}from"../locale/language.js";import{toEsriApiGeometry,toPortalGeometry}from"../portal/Geometry.js";import{checkArg,assertNever}from"../utilities/checkArg.js";import{parse as parseDate,format as formatDate,DEFAULT_PARSING_FORMATS,DateFormat,INVALID_DATE}from"../utilities/date.js";import{esriToWKT,esriToGeoJSON,geoJSONToEsri,wktToEsri,esriWkidToWkt,esriWktToWkid,project,isPoint,isMultipoint,isPolyline,isPolygon,isExtent}from"../utilities/geometry.js";import{getLogger}from"../utilities/log.js";import{parse as parseNumber,format as formatNumber,NumberFormat,isNumeric}from"../utilities/number.js";import{Feature}from"./Feature.js";import{FeatureSet}from"./FeatureSet.js";const FORMULA_TRIGGER_CHARS=["=","-","+","@"],QUOTE='"',FIELD_NAME_REGEX=/[^a-zA-Z\d_]/g,DEFAULT_WINDOWS_ROW_DELIMITER="\r\n",DEFAULT_UNIX_ROW_DELIMITER="\n",DEFAULT_SHEET_NAME="sheet1",DEFAULT_EXCEL_DATE_FORMATS=[...DEFAULT_PARSING_FORMATS.map(_convertToExcelDateFormatString),"M/d/yy"],shapefileNameRegex=/(\w+)_(point|multipoint|polyline|polygon)z?/;var DBaseTypes;function _getConvertLogger(){return getLogger("geocortex.api.data.convert")}!function(e){e.DATE="D",e.NUMBER="N",e.STRING="C",e.BOOLEAN="L"}(DBaseTypes||(DBaseTypes={}));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 async function toCsv(e,t){checkArg("featureSet",e).isNotMissing();const r=Array.from(e),o={...{useFormattedValues:!1,alwaysQuote:!1,escapeFormulaChars:!0,delimiter:",",dateFormat:DateFormat.ROUND_TRIP,geometryFormat:r.some((e=>void 0!==e.geometry&&null!==e.geometry))?GeometryFormat.WKT:GeometryFormat.NONE,includeByteOrderMark:!0,outSpatialReference:SpatialReference.WGS84,includeHeaderRow:!0,outFields:_getDefaultOutFields(e.source),rowDelimiter:navigator.platform.startsWith("Win")?"\r\n":"\n"},...t},{includeByteOrderMark:a,includeHeaderRow:n,delimiter:s,outFields:i,rowDelimiter:m}=o,u=[];a&&u.push("\ufeff");const l=_getGeometryColumns(r,o),c=_getAttributeColumns(r,i,e.schema,!0),f=_getAttributeColumns(r,i,e.schema,!1);if(n){const e=[];for(const t of l)e.push(_quotify(t,o));for(const t of c)e.push(_quotify(t,o));for(const t of f)e.push(_quotify(t,o));const t=e.join(s)+m;u.push(t)}await Promise.all(r.map((async e=>{const t=[],r=(t,r)=>_quotify(_stringify(_getAttributeValue(e,t,r),r),r);t.push(...await _getCSVGeometry(e.geometry,o)),t.push(...c.map((e=>r(e,o)))),t.push(...f.map((e=>r(e,o))));const a=`${t.join(s)}${m}`;u.push(a)})));return new Blob(u,{type:"text/plain",endings:"\n"===m||"\r\n"===m?"transparent":"native"})}export async function csvToFeatureSet(e,t){let r;if(checkArg("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={...{delimiter:",",escapeFormulaChars:!0,includeHeaderRow:!0,outFields:["*"],inSpatialReference:SpatialReference.WGS84,generatePrimaryKey:!0,primaryKeyField:"OBJECTID"},...t,detectOid:!t?.primaryKeyField},a=_parseCSV(r,o.rowDelimiter||_parseRowDelimiter(r),o.delimiter),n=_parseGeometries(a,o),s=_parseSchema(a,n,o),i=await _parseFeatures(a,n,s,o);return new FeatureSet({features:i,schema:s})}export async function toXLSX(e,t){checkArg("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:_getDefaultOutFields(e.source),outSpatialReference:SpatialReference.WGS84,dateFormat:DateFormat.DEFAULT,numberFormat:NumberFormat.DEFAULT,sheetName:"sheet1"},...t},{outFields:a,includeHeaderRow:n,numberFormat:s}=o,i=[],m=_getGeometryColumns(r,o),u=_getAttributeColumns(r,a,e.schema,!0),l=_getAttributeColumns(r,a,e.schema,!1);if(n){const t=m.concat(u).concat(_getXlsxColumnName(l,e.source));i.push(t)}await Promise.all(r.map((async e=>{const t=[];t.push(...await _getGeometry(e.geometry,o));for(const r of u){const a=_toXLSXValue(e.attributes.get(r),o);t.push(a)}for(const r of l){const a=_toXLSXValue(_getAttributeValue(e,r,o),o);t.push(a)}t.every((e=>"string"!=typeof e||e.length<=32767))?i.push(t):_getConvertLogger().warn(`toXLSX cell limit exceeded, feature (${e.primaryKey??e.id}) omitted.`)})));const c=await import("xlsx"),f={SheetNames:[],Sheets:{}},p=c.utils.aoa_to_sheet(i,{cellDates:!0});for(const e of Object.keys(p).filter((e=>!e.startsWith("!")))){const t=p[e];"d"===t.t?t.z=_convertToExcelDateFormatString(o.dateFormat??DateFormat.ROUND_TRIP):"n"===t.t&&(t.z=_convertToExcelNumberFormatString(s))}f.SheetNames.push(o.sheetName),f.Sheets[o.sheetName]=p;const y=c.write(f,{type:"binary",bookType:"xlsx",compression:!0,bookSST:!0,cellDates:!0}),d=new Uint8Array(y.length);for(let e=0;e<y.length;e++)d[e]=y.charCodeAt(e);return new Blob([d.buffer],{type:"text/plain"})}export async function xlsxToFeatureSet(e,t){checkArg("xlsxData",e).isNotMissing();const r={...{includeHeaderRow:!0,escapeFormulaChars:!0,outFields:["*"],inSpatialReference:SpatialReference.WGS84,generatePrimaryKey:!0,primaryKeyField:"OBJECTID"},...t,detectOid:!t?.primaryKeyField},o=await _parseXLSX(e,r),a=_parseGeometries(o,r),n=_parseSchema(o,a,r),s=await _parseFeatures(o,a,n,r);return new FeatureSet({features:s,schema:n})}export async function toShapefile(e,t){checkArg("featureSet",e).isNotMissing();const[{default:r},o]=await Promise.all([import("jszip"),import("../forked-libs/shp-write/index.js")]),a=Array.from(e),n={...{useFormattedValues:!1,outFields:_getDefaultOutFields(e.source),fileName:e.title||"export"},...t},{outFields:s,outSpatialReference:i,fileName:m}=n,u=e=>e.geometry.hasZ||e.geometry.hasM,l=new Map,c=a.filter((e=>isPoint(e.geometry)));l.set("POINTZ",c.filter(u)),l.set("POINT",c.filter((e=>!u(e))));const f=a.filter((e=>isMultipoint(e.geometry)));l.set("MULTIPOINTZ",f.filter(u)),l.set("MULTIPOINT",f.filter((e=>!u(e))));const p=a.filter((e=>isPolyline(e.geometry)));l.set("POLYLINEZ",p.filter(u)),l.set("POLYLINE",p.filter((e=>!u(e))));const y=a.filter((e=>isPolygon(e.geometry)||isExtent(e.geometry)));l.set("POLYGONZ",y.filter(u)),l.set("POLYGON",y.filter((e=>!u(e))));const d=_getAttributeColumns(a,s,e.schema,!0);let g=_getAttributeColumns(a,s,e.schema,!1);g=d.concat(g);const h=new r,F=Array.from(l.keys()).filter((e=>l.get(e).length>0));await Promise.all(F.map((async t=>{const r=l.get(t),a=await Promise.all(r.map((e=>_projectGeometry(e.geometry,i)))),s=await _getDBaseSpatialReferenceWKT(a),u=n.useFormattedValues?Object.assign({},...g.map((e=>({[e]:DBaseTypes.STRING})))):_getDBaseColumnTypes(r,g,e.schema,"timestamp"===n.dateFormat),c=_getDBaseGeometries(a),f=_getDbaseValues(r,g,u,n);o.write(f,t,c,((e,r)=>{const o=F.length>1?`${m}_${t.toLowerCase()}`:m;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 _=await h.generateAsync({type:"uint8array"});return new Blob([_.buffer],{type:"text/plain"})}export async function shapefileToFeatureSet(e,t){checkArg("shapefileData",e).isNotMissing();const r={outFields:["*"],includeHeaderRow:!0,generatePrimaryKey:!0,primaryKeyField:"OBJECTID",...t,detectOid:!t?.primaryKeyField},o=new Promise(((t,r)=>{const o=new FileReader;o.onload=()=>{t(o.result)},o.onerror=()=>{r(o.error)},o.readAsArrayBuffer(e)})),[{default:a},{default:n}]=await Promise.all([import("jszip"),import("shpjs")]),s=await o,i=await a.loadAsync(new Uint8Array(s)),m=i.filter((()=>!0)).map((e=>e.name));let u,l=m.filter((e=>e.endsWith(".shp"))).map((e=>e.substring(0,e.length-4)));if(l=_parseShapefileNames(l),m.some((e=>e.endsWith(".prj")))&&!l.every((e=>m.includes(`${e}.prj`))))throw new Error("Shapefile zip must contain the same prj file for each separate shapefile");await Promise.all(m.filter((e=>e.endsWith(".prj"))).map((async e=>{const t=await i.file(e).async("string");if(u){if(t!==u)throw new Error("Shapefile zip must contain the same prj file for each separate shapefile")}else u=t})));const c={geometries:[],columnCount:0,columnIndex:0};let f=[];for(const e of l){if(!m.includes(`${e}.shx`)||!m.includes(`${e}.dbf`))throw new Error("Shapefile must contain shp, shx, and dbf files.");const t=await i.file(`${e}.shp`).async("uint8array"),r=n.parseShp(t),o=await i.file(`${e}.dbf`).async("uint8array"),a=n.parseDbf(o);if(a.length!==r.length)throw new Error("Shapefile must contain shp, shx, and dbf files.");const s=await Promise.all(r.map((e=>_parseShpGeometry(e,u))));c.geometries=c.geometries.concat(s),f=f.concat(a)}const p=_parseDBaseData(f),y=_parseSchema(p,c,r),d=await _parseFeatures(p,c,y,r);return new FeatureSet({features:d,schema:y})}function _getGeometryColumns(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 _getAttributeColumns(e,t,r,o){const a=r.fields.filter((e=>"oid"===e.type)).map((e=>e.name)).toArray();if(o)return a;if(t&&!t.includes("*"))return t.filter((e=>!a.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)||a.includes(e)||o.includes(e)||o.push(e);return o=o.sort(),t.concat(o)}}function _getXlsxColumnName(e,t){const r=t?.schema?.fieldExtensions.initializedItems.map((e=>e.field));return e.map((e=>r?.find((t=>t.name===e))?.alias??e))}function _getDefaultOutFields(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 _getCSVGeometry(e,t){let r=await _getGeometry(e,t);return t.geometryFormat!==GeometryFormat.XYZ&&t.geometryFormat!==GeometryFormat.XY&&t.geometryFormat!==GeometryFormat.LAT_LON||(r=r.map((e=>void 0===e?"":_stringify(e,t)))),r.map((e=>""===e?"":_quotify(e,t)))}async function _getGeometry(e,t){const r=await _projectGeometry(e,t.outSpatialReference);if(t.geometryFormat===GeometryFormat.XYZ){if(!r)return["","",""];if(!isPoint(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(!isPoint(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(!isPoint(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(toPortalGeometry(r))]:[""]:t.geometryFormat===GeometryFormat.WKT?r?[esriToWKT(r)]:[""]:t.geometryFormat===GeometryFormat.GEO_JSON?r?[JSON.stringify(esriToGeoJSON(r))]:[""]:[]}async function _projectGeometry(e,t){return e?.spatialReference&&!e.spatialReference.equals(t)&&t?(await project([e],t))[0]:e}function _quotify(e,t){const r=[t.delimiter,'"',"\r","\n",t.rowDelimiter];if(t.alwaysQuote||r.some((t=>e.includes(t)))){return`"${e.replace(new RegExp('"',"g"),'""')}"`}return e}function _stringify(e,t){if(null==e)return"";if(!t.useFormattedValues){if("number"==typeof e){const r=t.numberFormat||NumberFormat.ROUND_TRIP;return formatNumber(r,e)}if(e instanceof Date)return"timestamp"===t.dateFormat?e.getTime().toString():formatDate({format:t.dateFormat,timeZone:"UTC"},e)}let r=e.toString();return t.escapeFormulaChars&&(r=escapeFormulaChars(r)),r}function _getAttributeValue(e,t,r){if(r.useFormattedValues||_hasCodedDomain(e,t))return e.presentableAttributes.get(t)??e.attributes.get(t);if("date"===e.schema.findFieldByName(t)?.type){const r=parseDate(e.attributes.get(t));if(!isNaN(r.getTime()))return r}return e.attributes.get(t)??e.presentableAttributes.get(t)}function _hasCodedDomain(e,t){return t===e.schema.typeIdField||("coded-value"===e.type?.domains?.[t]?.type||"coded-value"===e.schema.findFieldByName(t)?.domain?.type)}function escapeFormulaChars(e){for(const t of FORMULA_TRIGGER_CHARS)if(e.startsWith(t))return`\t${e}`;return e}function _parseRowDelimiter(e){let t="\n";return _forDelimiter(e,"\r\n",((r,o)=>(0===r&&o===e.length||(t="\r\n"),!1))),t}function _parseCSV(e,t,r){const o=[];if(_forDelimiter(e,t,((t,a)=>{const n=e.substring(t,a);return n.length>0&&o.push(((e,t)=>{const o=[];return _forDelimiter(e,r,((r,a)=>{const n=e.substring(r,a);return o.push({raw:_parseQuotes(n,t,o.length)}),!0})),o})(n,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}function _parseQuotes(e,t,r){const o=e.startsWith('"'),a=e.endsWith('"');if(o&&!a||!o&&a)throw new Error(`Detected invalid CSV: Missing opening or closing quote for value at row:${t} column:${r}`);const n=o?e.substring('"'.length,e.length-'"'.length):e;let s=-1;return _forDelimiter(n,'"',((e,o)=>{if(o===n.length)return!0;if(s<0){if(o!==n.length)return s=o,!0}else if(o===s+'"'.length)return s=-1,!0;throw new Error(`Detected invalid CSV: Non-escaped quote for value at row:${t} column:${r}`)})),n.replace(new RegExp('""',"g"),'"')}function _forDelimiter(e,t,r){let o,a=!1,n=0,s=0;for(;o=e.indexOf(t,n),!(o<0);){for(let t=n;t<o;)e.substring(t).startsWith('"')?(a=!a,t+='"'.length):t++;const i=o+t.length;if(!a){const e=r(s,o);if(s=i,!e)break}n=i}r(s,e.length)}const geometryTypeHeaders={[GeometryFormat.XYZ]:[["x","y","z"]],[GeometryFormat.XY]:[["x","y"]],[GeometryFormat.LAT_LON]:[["lat","lon"],["lat","long"],["latitude","longitude"]],[GeometryFormat.ARCGIS_JSON]:[["geometry"]],[GeometryFormat.GEO_JSON]:[["geometry"]],[GeometryFormat.WKT]:[["geometry"]]};function _parseArcGisJson(e,t){const r=JSON.parse(e),o=toEsriApiGeometry(r);return r.spatialReference||(o.spatialReference=t),o}function _parseGeoJson(e,t){const r=geoJSONToEsri(JSON.parse(e));return r.spatialReference=t,r}function _parseWkt(e,t){const r=wktToEsri(e);return r.spatialReference=t,r}function _findGeometryFormatIndex(e,t){const r=geometryTypeHeaders[t];for(const t of r){const r=e.findIndex(((r,o)=>!(o+t.length>e.length)&&t.every(((t,r)=>e[o+r].raw.toString().toLowerCase()===t))));if(-1!==r)return r}}function _detectGeometry(e,t){return e.map(((e,r)=>{const o=e?.raw;if("string"==typeof o&&""!==o)try{return t(o,void 0),r}catch{return}})).find((e=>void 0!==e))}function _parseGeometries(e,t){const r=t.includeHeaderRow?e.slice(1):e;if(t.geometryFormat===GeometryFormat.NONE)return{columnCount:0,columnIndex:0};const o=(e,o)=>{const a=o===GeometryFormat.XYZ,n=o===GeometryFormat.LAT_LON,s=a?3:2;return{columnCount:s,columnIndex:e,geometries:r.map((r=>{if(r.length>=e+s&&isNumeric(r[e+0].raw)&&isNumeric(r[e+1].raw)&&(!a||isNumeric(r[e+2].raw)))return new Point({x:parseNumber(n?r[e+1].raw:r[e+0].raw),y:parseNumber(n?r[e+0].raw:r[e+1].raw),z:a?parseNumber(r[e+2].raw):0,spatialReference:t.inSpatialReference})}))}},a=(e,o)=>({columnCount:1,columnIndex:e,geometries:r.map((t=>t[e])).map((e=>{if(""!==e.raw)return o(e.raw.toString(),t.inSpatialReference)}))});if(t.geometryFormat){const r=_findGeometryFormatIndex(e[0],t.geometryFormat);if(t.includeHeaderRow&&void 0===r)throw new Error(`Error parsing CSV: Expected geometry columns ${geometryTypeHeaders[t.geometryFormat][0].join(",")} are missing for GeometryType.${t.geometryFormat}`);return((e,t)=>{switch(t){case GeometryFormat.NONE:return{columnCount:0,columnIndex:0};case GeometryFormat.LAT_LON:case GeometryFormat.XYZ:case GeometryFormat.XY:return o(e,t);case GeometryFormat.ARCGIS_JSON:return a(e,_parseArcGisJson);case GeometryFormat.GEO_JSON:return a(e,_parseGeoJson);case GeometryFormat.WKT:return a(e,_parseWkt);default:return assertNever(t,new Error(`Unknown geometry format "${t}".`))}})(r??0,t.geometryFormat)}if(t.includeHeaderRow){const t=_findGeometryFormatIndex(e[0],GeometryFormat.ARCGIS_JSON);if(void 0!==t)for(const e of[_parseArcGisJson,_parseGeoJson,_parseWkt])try{return a(t,e)}catch(e){}const r=[GeometryFormat.XYZ,GeometryFormat.XY,GeometryFormat.LAT_LON];for(const t of r){const r=_findGeometryFormatIndex(e[0],t);if(void 0!==r)return o(r,t)}}for(const e of[_parseArcGisJson,_parseGeoJson,_parseWkt])try{const t=_detectGeometry(r[0],e);return a(t,e)}catch(e){}return{columnCount:0,columnIndex:0}}function _parseSchema(e,t,r){const o={fields:[]};let a=0;for(let s=t.columnCount;s<e[0].length;s++){if(n=s,0!==t.columnCount&&n>=t.columnIndex&&n<t.columnIndex+t.columnCount)continue;const i=_parseFieldType(e,s,r);let m=e[0][s].raw.toString(),u=m.replace(FIELD_NAME_REGEX,"_");if(r.includeHeaderRow||(u="field"+ ++a,m=translate("gcx.api.data.convert.import-field-alias",a)),!u)throw new Error("Error parsing CSV or XLSX: Header cannot contain blank values");o.fields.push({alias:m,name:u,type:i})}var n;if(o.spatialReference=r.outSpatialReference,t.geometries?.length){const e=t.geometries.filter((e=>void 0!==e)).map((e=>e.type)),r=e[0];o.geometryType=e.every((e=>e===r))?r:void 0}if(r.generatePrimaryKey&&!o.fields.find((e=>"esriFieldTypeOID"===e.type))){const e=o.fields.length+1,t=!!o.fields.find((e=>"id"===e.name.toLowerCase()));o.fields.push({name:t?`field${e}`:"id",alias:t?translate("gcx.api.data.convert.import-field-alias",e):"id",type:"esriFieldTypeOID"})}return o}function _parseFieldType(e,t,r){let o=!1,a=!0,n=!0,s=!0;const i=new Set,m=r.includeHeaderRow?e[0]:[],u=r.includeHeaderRow?e.slice(1):e;for(const e of u){const m=e[t];""!==m.raw&&(i.add(m.raw),o=!0,a&&(a=isNumeric(m.raw)||Number.isNaN(m.raw)),n&&(n=m.raw instanceof Date||parseDate(r.dateFormat||DEFAULT_PARSING_FORMATS,m.raw)!==INVALID_DATE),s&&(s=parseDate(r.dateFormat||DEFAULT_EXCEL_DATE_FORMATS,m.formatted)!==INVALID_DATE))}const l=i.size===u.length;return r.primaryKeyField&&m[t]?.raw===r.primaryKeyField||r.detectOid&&o&&l&&a?(r.detectOid=!1,"esriFieldTypeOID"):o&&s?"esriFieldTypeDate":o&&a?"esriFieldTypeDouble":o&&n?"esriFieldTypeDate":"esriFieldTypeString"}async function _parseFeatures(e,t,r,o){const a=[],n=o.includeHeaderRow?e.slice(1):e,s=(e,r)=>0===t.columnCount||(r<t.columnIndex||r>=t.columnIndex+t.columnCount);return await Promise.all(n.map((async(e,n)=>{const i=new Feature;for(let t=0;t<r.fields.length;t++){const a=r.fields[t],m=e.filter(s);if(o.outFields.includes("*")||o.outFields.includes(a.name)){let e=await _parseValue(m[t]?.raw,a,o);"esriFieldTypeOID"===a.type&&null===e&&(e=n),i.attributes.set(a.name,e)}}t.geometries&&(i.geometry=await _projectGeometry(t.geometries[n],o.outSpatialReference)),a.push(i)}))),a}async function _parseValue(e,t,r){if("esriFieldTypeDouble"===t.type||"esriFieldTypeOID"===t.type)return"number"==typeof e?e:e?parseNumber(e):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:parseDate(e).getTime()}const o=e.toString();if(r.escapeFormulaChars&&o.startsWith("\t"))for(const e of FORMULA_TRIGGER_CHARS)if(o.length>1&&o.charAt(1)===e)return o.substring(1);return o}function _convertToExcelDateFormatString(e){switch(e){case DateFormat.DATE_SHORT:return"dd/MM/yyyy";case DateFormat.DATE_LONG:return"MMMM d, yyyy";case DateFormat.TIME_SHORT:return"h:mm AM/PM";case DateFormat.TIME_LONG:return"h:mm:ss AM/PM";case DateFormat.DATE_TIME_SHORT:case DateFormat.DEFAULT:return"MMM d yyyy h:mm AM/PM";case DateFormat.DATE_TIME_LONG:return"MMMM d yyyy h:mm AM/PM";case DateFormat.FULL:return"dddd, MMMM d yyyy h:mm AM/PM";case DateFormat.ISO_8601:case DateFormat.ROUND_TRIP:return'yyyy-MM-dd"T"HH:mm:ss';default:{const t=e.replace(/tt/g,"AM/PM");return t.includes("z")&&_getConvertLogger().warn("Warning: Excel will not recognize timezone format 'z', 'zz', or 'zzz'"),t.includes("h")&&!t.includes("AM/PM")&&_getConvertLogger().warn("Warning: Excel will interpret 'h' as 'H' if the format does not have an AM/PM designator"),t}}}function _convertToExcelNumberFormatString(e){switch(e){case NumberFormat.ACCOUNTING:return'_("$"* #,##0.00_);_("$"* (#,##0.00);_("$"* "-"??_);_(@_)';case NumberFormat.CURRENCY:return'"$"#,##0.00';case NumberFormat.FIXED_POINT:case NumberFormat.DEFAULT:return"0.0000";case NumberFormat.NUMBER:return"#,##0.0000";case NumberFormat.PERCENT:return"0%";case NumberFormat.ROUND_TRIP:return"0.00000";default:return e}}function _toXLSXValue(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}let r=e.toString();return t.escapeFormulaChars&&(r=escapeFormulaChars(r)),r}async function _parseXLSX(e,t){const r=await import("xlsx"),o=new Promise(((o,a)=>{const n=new FileReader;n.onload=()=>{const e=new Uint8Array(n.result);let a="";for(const t of e)a+=String.fromCharCode(t);const s=r.read(a,{type:"binary",cellDates:!0}),i=t.sheetName||s.SheetNames[0],m=s.Sheets[i];o(m)},n.onerror=()=>{a(n.error)},n.readAsArrayBuffer(e)})),a=await o,n=r.utils.decode_range(a["!ref"]),s=[];for(let e=n.s.r;e<=n.e.r;e++){const t=[];for(let o=n.s.c;o<=n.e.c;o++){const n=a[`${r.utils.encode_cell({r:e,c:o})}`];t.push(n?{raw:n.v,formatted:"s"===n.t?void 0:n.w}:{raw:""})}s.push(t)}return s}async function _getDBaseSpatialReferenceWKT(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??esriWkidToWkt(t??SpatialReference.WGS84.wkid)}function _getDBaseColumnTypes(e,t,r,o){const a={};for(const n of t){if(e.some((e=>_hasCodedDomain(e,n)))){a[n]=DBaseTypes.STRING;continue}const t=r?r.fields.find((e=>e.name===n)):void 0;if(t){switch(t.type){case"oid":case"double":case"integer":case"single":case"small-integer":a[n]=DBaseTypes.NUMBER;break;case"date":a[n]=o?DBaseTypes.NUMBER:DBaseTypes.DATE;break;default:a[n]=DBaseTypes.STRING}continue}const s=(e,t)=>e.attributes.get(t)??e.presentableAttributes.get(t);e.every((e=>s(e,n)instanceof Date||void 0===s(e,n)))&&e.some((e=>s(e,n)instanceof Date))?a[n]=o?DBaseTypes.NUMBER:DBaseTypes.DATE:e.every((e=>"number"==typeof s(e,n)||void 0===s(e,n)))&&e.some((e=>"number"==typeof s(e,n)))?a[n]=DBaseTypes.NUMBER:e.every((e=>"boolean"==typeof s(e,n)||void 0===s(e,n)))&&e.some((e=>"boolean"==typeof s(e,n)))?a[n]=DBaseTypes.BOOLEAN:a[n]=DBaseTypes.STRING}return a}function _getDBaseGeometries(e){return e.map((e=>{if(isPoint(e)){const{x:t,y:r,z:o,m:a}=e,n=[t,r];return e.hasZ&&n.push(o),e.hasM&&n.push(a),_padZValues(n,e)}if(isMultipoint(e))return _padZValuesArray(e.points,e);if(isPolyline(e))return _padZValues2DArray(e.paths,e);if(isPolygon(e))return _padZValues2DArray(e.rings,e);if(isExtent(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.")}))}function _padZValues(e,t){return 3===e.length&&!t.hasZ&&t.hasM?[e[0],e[1],void 0,e[2]]:e}function _padZValuesArray(e,t){return e.map((e=>_padZValues(e,t)))}function _padZValues2DArray(e,t){return e.map((e=>_padZValuesArray(e,t)))}function _getDbaseValues(e,t,r,o){const a=[];for(const n of e){const e={};for(const a of t){let t=_getAttributeValue(n,a,o);if(null==t&&(t=""),o.useFormattedValues)t=t.toString();else{t=getDbaseValue(t,r[a],o)}e[a]=t}a.push(e)}return a}function getDbaseValue(e,t,r){switch(t){case DBaseTypes.NUMBER:return e instanceof Date?e.getTime():parseNumber(e);case DBaseTypes.STRING:return e instanceof Date?formatDate({format:r.dateFormat??DateFormat.ROUND_TRIP,timeZone:"UTC"},e):"number"==typeof e?formatNumber(r.numberFormat??NumberFormat.DEFAULT,e):e.toString();case DBaseTypes.BOOLEAN:return!!e;case DBaseTypes.DATE:return parseDate(e);default:return e.toString()}}function _parseShapefileNames(e){if(!e.length)return[];let t=e[0];const r=t.match(shapefileNameRegex);return r?(t=r[1],e.filter((e=>{const r=e.match(shapefileNameRegex);return r&&r[1]===t}))):[t]}function _parseDBaseData(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]})))))]}function _parseShpPointGeometry(e){checkArg("geometry.coordinates",e.type).matches("Point"),checkArg("geometry.coordinates",e.coordinates).satisfies((e=>"number"==typeof e||Array.isArray(e)));const[t,r,o]=e.coordinates,a=new Point({x:t,y:r,spatialReference:SpatialReference.WGS84});if(Array.isArray(o)){const[e,t]=o;!e&&!t||e?a.z=e:a.m=t}return a}async function _parseShpGeometry(e,t){const r=isPoint(e)?_parseShpPointGeometry(e):geoJSONToEsri(e);if(t){let e;try{const r=await esriWktToWkid(t);e=new SpatialReference({wkid:parseNumber(r)})}catch{}e||(e=new SpatialReference({wkt:t})),r.spatialReference=e}return r}
|
|
1
|
+
import Point from"@arcgis/core/geometry/Point";import SpatialReference from"@arcgis/core/geometry/SpatialReference";import{translate}from"../locale/language.js";import{toEsriApiGeometry,toPortalGeometry}from"../portal/Geometry.js";import{checkArg,assertNever}from"../utilities/checkArg.js";import{parse as parseDate,format as formatDate,DEFAULT_PARSING_FORMATS,DateFormat,INVALID_DATE}from"../utilities/date.js";import{esriToWKT,esriToGeoJSON,geoJSONToEsri,wktToEsri,esriWkidToWkt,esriWktToWkid,project,isPoint,isMultipoint,isPolyline,isPolygon,isExtent}from"../utilities/geometry.js";import{getLogger}from"../utilities/log.js";import{parse as parseNumber,format as formatNumber,NumberFormat,isNumeric}from"../utilities/number.js";import{Feature}from"./Feature.js";import{FeatureSet}from"./FeatureSet.js";const FORMULA_TRIGGER_CHARS=["=","-","+","@"],QUOTE='"',FIELD_NAME_REGEX=/[^a-zA-Z\d_]/g,DEFAULT_WINDOWS_ROW_DELIMITER="\r\n",DEFAULT_UNIX_ROW_DELIMITER="\n",DEFAULT_SHEET_NAME="sheet1",DEFAULT_EXCEL_DATE_FORMATS=[...DEFAULT_PARSING_FORMATS.map(_convertToExcelDateFormatString),"M/d/yy"],shapefileNameRegex=/(\w+)_(point|multipoint|polyline|polygon)z?/;var DBaseTypes;function _getConvertLogger(){return getLogger("geocortex.api.data.convert")}!function(e){e.DATE="D",e.NUMBER="N",e.STRING="C",e.BOOLEAN="L"}(DBaseTypes||(DBaseTypes={}));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 async function toCsv(e,t){checkArg("featureSet",e).isNotMissing();const r=Array.from(e),o={...{useFormattedValues:!1,alwaysQuote:!1,escapeFormulaChars:!0,delimiter:",",dateFormat:DateFormat.ROUND_TRIP,geometryFormat:r.some((e=>void 0!==e.geometry&&null!==e.geometry))?GeometryFormat.WKT:GeometryFormat.NONE,includeByteOrderMark:!0,outSpatialReference:SpatialReference.WGS84,includeHeaderRow:!0,outFields:_getDefaultOutFields(e.source),rowDelimiter:navigator.platform.startsWith("Win")?"\r\n":"\n"},...t},{includeByteOrderMark:a,includeHeaderRow:n,delimiter:s,outFields:i,rowDelimiter:m}=o,u=[];a&&u.push("\ufeff");const l=_getGeometryColumns(r,o),c=_getAttributeColumns(r,i,e.schema,!0),f=_getAttributeColumns(r,i,e.schema,!1);if(n){const e=[];for(const t of l)e.push(_quotify(t,o));for(const t of c)e.push(_quotify(t,o));for(const t of f)e.push(_quotify(t,o));const t=e.join(s)+m;u.push(t)}await Promise.all(r.map((async e=>{const t=[],r=(t,r)=>_quotify(_stringify(_getAttributeValue(e,t,r),r),r);t.push(...await _getCSVGeometry(e.geometry,o)),t.push(...c.map((e=>r(e,o)))),t.push(...f.map((e=>r(e,o))));const a=`${t.join(s)}${m}`;u.push(a)})));return new Blob(u,{type:"text/plain",endings:"\n"===m||"\r\n"===m?"transparent":"native"})}export async function csvToFeatureSet(e,t){let r;if(checkArg("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={...{delimiter:",",escapeFormulaChars:!0,includeHeaderRow:!0,outFields:["*"],inSpatialReference:SpatialReference.WGS84,generatePrimaryKey:!0,primaryKeyField:"OBJECTID"},...t,detectOid:!t?.primaryKeyField},a=_parseCSV(r,o.rowDelimiter||_parseRowDelimiter(r),o.delimiter),n=_parseGeometries(a,o),s=_parseSchema(a,n,o),i=await _parseFeatures(a,n,s,o);return new FeatureSet({features:i,schema:s})}export async function toXLSX(e,t){checkArg("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:_getDefaultOutFields(e.source),outSpatialReference:SpatialReference.WGS84,dateFormat:DateFormat.DEFAULT,numberFormat:NumberFormat.DEFAULT,sheetName:"sheet1"},...t},{outFields:a,includeHeaderRow:n,numberFormat:s}=o,i=[],m=_getGeometryColumns(r,o),u=_getAttributeColumns(r,a,e.schema,!0),l=_getAttributeColumns(r,a,e.schema,!1);if(n){const t=m.concat(u).concat(_getXlsxColumnName(l,e.source));i.push(t)}await Promise.all(r.map((async e=>{const t=[];t.push(...await _getGeometry(e.geometry,o));for(const r of u){const a=_toXLSXValue(e.attributes.get(r),o);t.push(a)}for(const r of l){const a=_toXLSXValue(_getAttributeValue(e,r,o),o);t.push(a)}t.every((e=>"string"!=typeof e||e.length<=32767))?i.push(t):_getConvertLogger().warn(`toXLSX cell limit exceeded, feature (${e.primaryKey??e.id}) omitted.`)})));const c=await import("xlsx"),f={SheetNames:[],Sheets:{}},p=c.utils.aoa_to_sheet(i,{cellDates:!0});for(const e of Object.keys(p).filter((e=>!e.startsWith("!")))){const t=p[e];"d"===t.t?t.z=_convertToExcelDateFormatString(o.dateFormat??DateFormat.ROUND_TRIP):"n"===t.t&&(t.z=_convertToExcelNumberFormatString(s))}f.SheetNames.push(o.sheetName),f.Sheets[o.sheetName]=p;const y=c.write(f,{type:"binary",bookType:"xlsx",compression:!0,bookSST:!0,cellDates:!0}),d=new Uint8Array(y.length);for(let e=0;e<y.length;e++)d[e]=y.charCodeAt(e);return new Blob([d.buffer],{type:"text/plain"})}export async function xlsxToFeatureSet(e,t){checkArg("xlsxData",e).isNotMissing();const r={...{includeHeaderRow:!0,escapeFormulaChars:!0,outFields:["*"],inSpatialReference:SpatialReference.WGS84,generatePrimaryKey:!0,primaryKeyField:"OBJECTID"},...t,detectOid:!t?.primaryKeyField},o=await _parseXLSX(e,r),a=_parseGeometries(o,r),n=_parseSchema(o,a,r),s=await _parseFeatures(o,a,n,r);return new FeatureSet({features:s,schema:n})}export async function toShapefile(e,t){checkArg("featureSet",e).isNotMissing();const[{default:r},o]=await Promise.all([import("jszip"),import("../forked-libs/shp-write/index.js")]),a=Array.from(e),n={...{useFormattedValues:!1,outFields:_getDefaultOutFields(e.source),fileName:e.title||"export"},...t},{outFields:s,outSpatialReference:i,fileName:m}=n,u=e=>e.geometry.hasZ||e.geometry.hasM,l=new Map,c=a.filter((e=>isPoint(e.geometry)));l.set("POINTZ",c.filter(u)),l.set("POINT",c.filter((e=>!u(e))));const f=a.filter((e=>isMultipoint(e.geometry)));l.set("MULTIPOINTZ",f.filter(u)),l.set("MULTIPOINT",f.filter((e=>!u(e))));const p=a.filter((e=>isPolyline(e.geometry)));l.set("POLYLINEZ",p.filter(u)),l.set("POLYLINE",p.filter((e=>!u(e))));const y=a.filter((e=>isPolygon(e.geometry)||isExtent(e.geometry)));l.set("POLYGONZ",y.filter(u)),l.set("POLYGON",y.filter((e=>!u(e))));const d=_getAttributeColumns(a,s,e.schema,!0);let g=_getAttributeColumns(a,s,e.schema,!1);g=d.concat(g);const h=new r,F=Array.from(l.keys()).filter((e=>l.get(e).length>0));await Promise.all(F.map((async t=>{const r=l.get(t),a=await Promise.all(r.map((e=>_projectGeometry(e.geometry,i)))),s=await _getDBaseSpatialReferenceWKT(a),u=n.useFormattedValues?Object.assign({},...g.map((e=>({[e]:DBaseTypes.STRING})))):_getDBaseColumnTypes(r,g,e.schema,"timestamp"===n.dateFormat),c=_getDBaseGeometries(a),f=_getDbaseValues(r,g,u,n);o.write(f,t,c,((e,r)=>{const o=F.length>1?`${m}_${t.toLowerCase()}`:m;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 _=await h.generateAsync({type:"uint8array"});return new Blob([_.buffer],{type:"text/plain"})}export async function shapefileToFeatureSet(e,t){checkArg("shapefileData",e).isNotMissing();const r={outFields:["*"],includeHeaderRow:!0,generatePrimaryKey:!0,primaryKeyField:"OBJECTID",...t,detectOid:!t?.primaryKeyField},o=new Promise(((t,r)=>{const o=new FileReader;o.onload=()=>{t(o.result)},o.onerror=()=>{r(o.error)},o.readAsArrayBuffer(e)})),[{default:a},{default:n}]=await Promise.all([import("jszip"),import("shpjs")]),s=await o,i=await a.loadAsync(new Uint8Array(s)),m=i.filter((()=>!0)).map((e=>e.name));let u,l=m.filter((e=>e.endsWith(".shp"))).map((e=>e.substring(0,e.length-4)));if(l=_parseShapefileNames(l),m.some((e=>e.endsWith(".prj")))&&!l.every((e=>m.includes(`${e}.prj`))))throw new Error("Shapefile zip must contain the same prj file for each separate shapefile");await Promise.all(m.filter((e=>e.endsWith(".prj"))).map((async e=>{const t=await i.file(e).async("string");if(u){if(t!==u)throw new Error("Shapefile zip must contain the same prj file for each separate shapefile")}else u=t})));const c={geometries:[],columnCount:0,columnIndex:0};let f=[];for(const e of l){if(!m.includes(`${e}.shx`)||!m.includes(`${e}.dbf`))throw new Error("Shapefile must contain shp, shx, and dbf files.");const t=await i.file(`${e}.shp`).async("uint8array"),r=n.parseShp(t),o=await i.file(`${e}.dbf`).async("uint8array"),a=n.parseDbf(o);if(a.length!==r.length)throw new Error("Shapefile must contain shp, shx, and dbf files.");const s=await Promise.all(r.map((e=>_parseShpGeometry(e,u))));c.geometries=c.geometries.concat(s),f=f.concat(a)}const p=_parseDBaseData(f),y=_parseSchema(p,c,r),d=await _parseFeatures(p,c,y,r);return new FeatureSet({features:d,schema:y})}function _getGeometryColumns(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 _getAttributeColumns(e,t,r,o){const a=r.fields.filter((e=>"oid"===e.type)).map((e=>e.name)).toArray();if(o)return a;if(t&&!t.includes("*"))return t.filter((e=>!a.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)||a.includes(e)||o.includes(e)||o.push(e);return o=o.sort(),t.concat(o)}}function _getXlsxColumnName(e,t){const r=t?.schema?.fieldExtensions.initializedItems.map((e=>e.field));return e.map((e=>r?.find((t=>t.name===e))?.alias??e))}function _getDefaultOutFields(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 _getCSVGeometry(e,t){let r=await _getGeometry(e,t);return t.geometryFormat!==GeometryFormat.XYZ&&t.geometryFormat!==GeometryFormat.XY&&t.geometryFormat!==GeometryFormat.LAT_LON||(r=r.map((e=>void 0===e?"":_stringify(e,t)))),r.map((e=>""===e?"":_quotify(e,t)))}async function _getGeometry(e,t){const r=await _projectGeometry(e,t.outSpatialReference);if(t.geometryFormat===GeometryFormat.XYZ){if(!r)return["","",""];if(!isPoint(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(!isPoint(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(!isPoint(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(toPortalGeometry(r))]:[""]:t.geometryFormat===GeometryFormat.WKT?r?[esriToWKT(r)]:[""]:t.geometryFormat===GeometryFormat.GEO_JSON?r?[JSON.stringify(esriToGeoJSON(r))]:[""]:[]}async function _projectGeometry(e,t){return e?.spatialReference&&!e.spatialReference.equals(t)&&t?(await project([e],t))[0]:e}function _quotify(e,t){const r=[t.delimiter,'"',"\r","\n",t.rowDelimiter];if(t.alwaysQuote||r.some((t=>e.includes(t)))){return`"${e.replace(new RegExp('"',"g"),'""')}"`}return e}function _stringify(e,t){if(null==e)return"";if(!t.useFormattedValues){if("number"==typeof e){const r=t.numberFormat||NumberFormat.ROUND_TRIP;return formatNumber(r,e)}if(e instanceof Date)return"timestamp"===t.dateFormat?e.getTime().toString():formatDate({format:t.dateFormat,timeZone:"UTC"},e)}let r=e.toString();return t.escapeFormulaChars&&(r=escapeFormulaChars(r)),r}function _getAttributeValue(e,t,r){if(r.useFormattedValues||_hasCodedDomain(e,t))return e.presentableAttributes.get(t)??e.attributes.get(t);if("date"===e.schema.findFieldByName(t)?.type){const r=parseDate(e.attributes.get(t));if(!isNaN(r.getTime()))return r}return e.attributes.get(t)??e.presentableAttributes.get(t)}function _hasCodedDomain(e,t){return t===e.schema.typeIdField||("coded-value"===e.type?.domains?.[t]?.type||"coded-value"===e.schema.findFieldByName(t)?.domain?.type)}function escapeFormulaChars(e){for(const t of FORMULA_TRIGGER_CHARS)if(e.startsWith(t))return`\t${e}`;return e}function _parseRowDelimiter(e){let t="\n";return _forDelimiter(e,"\r\n",((r,o)=>(0===r&&o===e.length||(t="\r\n"),!1))),t}function _parseCSV(e,t,r){const o=[];if(_forDelimiter(e,t,((t,a)=>{const n=e.substring(t,a);return n.length>0&&o.push(((e,t)=>{const o=[];return _forDelimiter(e,r,((r,a)=>{const n=e.substring(r,a);return o.push({raw:_parseQuotes(n,t,o.length)}),!0})),o})(n,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}function _parseQuotes(e,t,r){const o=e.startsWith('"'),a=e.endsWith('"');if(o&&!a||!o&&a)throw new Error(`Detected invalid CSV: Missing opening or closing quote for value at row:${t} column:${r}`);const n=o?e.substring('"'.length,e.length-'"'.length):e;let s=-1;return _forDelimiter(n,'"',((e,o)=>{if(o===n.length)return!0;if(s<0){if(o!==n.length)return s=o,!0}else if(o===s+'"'.length)return s=-1,!0;throw new Error(`Detected invalid CSV: Non-escaped quote for value at row:${t} column:${r}`)})),n.replace(new RegExp('""',"g"),'"')}function _forDelimiter(e,t,r){let o,a=!1,n=0,s=0;for(;o=e.indexOf(t,n),!(o<0);){for(let t=n;t<o;)e.substring(t).startsWith('"')?(a=!a,t+='"'.length):t++;const i=o+t.length;if(!a){const e=r(s,o);if(s=i,!e)break}n=i}r(s,e.length)}const geometryTypeHeaders={[GeometryFormat.XYZ]:[["x","y","z"]],[GeometryFormat.XY]:[["x","y"]],[GeometryFormat.LAT_LON]:[["lat","lon"],["lat","long"],["latitude","longitude"]],[GeometryFormat.ARCGIS_JSON]:[["geometry"]],[GeometryFormat.GEO_JSON]:[["geometry"]],[GeometryFormat.WKT]:[["geometry"]]};function _parseArcGisJson(e,t){const r=JSON.parse(e),o=toEsriApiGeometry(r);return r.spatialReference||(o.spatialReference=t),o}function _parseGeoJson(e,t){const r=geoJSONToEsri(JSON.parse(e));return r.spatialReference=t,r}function _parseWkt(e,t){const r=wktToEsri(e);return r.spatialReference=t,r}function _findGeometryFormatIndex(e,t){const r=geometryTypeHeaders[t];for(const t of r){const r=e.findIndex(((r,o)=>!(o+t.length>e.length)&&t.every(((t,r)=>e[o+r].raw.toString().toLowerCase()===t))));if(-1!==r)return r}}function _detectGeometry(e,t){return e.map(((e,r)=>{const o=e?.raw;if("string"==typeof o&&""!==o)try{return t(o,void 0),r}catch{return}})).find((e=>void 0!==e))}function _parseGeometries(e,t){const r=t.includeHeaderRow?e.slice(1):e;if(t.geometryFormat===GeometryFormat.NONE)return{columnCount:0,columnIndex:0};const o=(e,o)=>{const a=o===GeometryFormat.XYZ,n=o===GeometryFormat.LAT_LON,s=a?3:2;return{columnCount:s,columnIndex:e,geometries:r.map((r=>{if(r.length>=e+s&&isNumeric(r[e+0].raw)&&isNumeric(r[e+1].raw)&&(!a||isNumeric(r[e+2].raw)))return new Point({x:parseNumber(n?r[e+1].raw:r[e+0].raw),y:parseNumber(n?r[e+0].raw:r[e+1].raw),z:a?parseNumber(r[e+2].raw):0,spatialReference:t.inSpatialReference})}))}},a=(e,o)=>({columnCount:1,columnIndex:e,geometries:r.map((t=>t[e])).map((e=>{if(""!==e.raw)return o(e.raw.toString(),t.inSpatialReference)}))});if(t.geometryFormat){const r=_findGeometryFormatIndex(e[0],t.geometryFormat);if(t.includeHeaderRow&&void 0===r)throw new Error(`Error parsing CSV: Expected geometry columns ${geometryTypeHeaders[t.geometryFormat][0].join(",")} are missing for GeometryType.${t.geometryFormat}`);return((e,t)=>{switch(t){case GeometryFormat.NONE:return{columnCount:0,columnIndex:0};case GeometryFormat.LAT_LON:case GeometryFormat.XYZ:case GeometryFormat.XY:return o(e,t);case GeometryFormat.ARCGIS_JSON:return a(e,_parseArcGisJson);case GeometryFormat.GEO_JSON:return a(e,_parseGeoJson);case GeometryFormat.WKT:return a(e,_parseWkt);default:return assertNever(t,new Error(`Unknown geometry format "${t}".`))}})(r??0,t.geometryFormat)}if(t.includeHeaderRow){const t=_findGeometryFormatIndex(e[0],GeometryFormat.ARCGIS_JSON);if(void 0!==t)for(const e of[_parseArcGisJson,_parseGeoJson,_parseWkt])try{return a(t,e)}catch(e){}const r=[GeometryFormat.XYZ,GeometryFormat.XY,GeometryFormat.LAT_LON];for(const t of r){const r=_findGeometryFormatIndex(e[0],t);if(void 0!==r)return o(r,t)}}for(const e of[_parseArcGisJson,_parseGeoJson,_parseWkt])try{const t=_detectGeometry(r[0],e);return a(t,e)}catch(e){}return{columnCount:0,columnIndex:0}}function _parseSchema(e,t,r){const o={fields:[]};let a=0;for(let s=0;s<e[0].length;s++){if(n=s,0!==t.columnCount&&n>=t.columnIndex&&n<t.columnIndex+t.columnCount)continue;const i=_parseFieldType(e,s,r);let m=e[0][s].raw.toString(),u=m.replace(FIELD_NAME_REGEX,"_");if(r.includeHeaderRow||(u="field"+ ++a,m=translate("gcx.api.data.convert.import-field-alias",a)),!u)throw new Error("Error parsing CSV or XLSX: Header cannot contain blank values");o.fields.push({alias:m,name:u,type:i})}var n;if(o.spatialReference=r.outSpatialReference,t.geometries?.length){const e=t.geometries.filter((e=>void 0!==e)).map((e=>e.type)),r=e[0];o.geometryType=e.every((e=>e===r))?r:void 0}if(r.generatePrimaryKey&&!o.fields.find((e=>"esriFieldTypeOID"===e.type))){const e=o.fields.length+1,t=!!o.fields.find((e=>"id"===e.name.toLowerCase()));o.fields.push({name:t?`field${e}`:"id",alias:t?translate("gcx.api.data.convert.import-field-alias",e):"id",type:"esriFieldTypeOID"})}return o}function _parseFieldType(e,t,r){let o=!1,a=!0,n=!0,s=!0;const i=new Set,m=r.includeHeaderRow?e[0]:[],u=r.includeHeaderRow?e.slice(1):e;for(const e of u){const m=e[t];""!==m.raw&&(i.add(m.raw),o=!0,a&&(a=isNumeric(m.raw)||Number.isNaN(m.raw)),n&&(n=m.raw instanceof Date||parseDate(r.dateFormat||DEFAULT_PARSING_FORMATS,m.raw)!==INVALID_DATE),s&&(s=parseDate(r.dateFormat||DEFAULT_EXCEL_DATE_FORMATS,m.formatted)!==INVALID_DATE))}const l=i.size===u.length;return r.primaryKeyField&&m[t]?.raw===r.primaryKeyField||r.detectOid&&o&&l&&a?(r.detectOid=!1,"esriFieldTypeOID"):o&&s?"esriFieldTypeDate":o&&a?"esriFieldTypeDouble":o&&n?"esriFieldTypeDate":"esriFieldTypeString"}async function _parseFeatures(e,t,r,o){const a=[],n=o.includeHeaderRow?e.slice(1):e,s=(e,r)=>0===t.columnCount||(r<t.columnIndex||r>=t.columnIndex+t.columnCount);return await Promise.all(n.map((async(e,n)=>{const i=new Feature;for(let t=0;t<r.fields.length;t++){const a=r.fields[t],m=e.filter(s);if(o.outFields.includes("*")||o.outFields.includes(a.name)){let e=await _parseValue(m[t]?.raw,a,o);"esriFieldTypeOID"===a.type&&null===e&&(e=n),i.attributes.set(a.name,e)}}t.geometries&&(i.geometry=await _projectGeometry(t.geometries[n],o.outSpatialReference)),a.push(i)}))),a}async function _parseValue(e,t,r){if("esriFieldTypeDouble"===t.type||"esriFieldTypeOID"===t.type)return"number"==typeof e?e:e?parseNumber(e):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:parseDate(e).getTime()}const o=e.toString();if(r.escapeFormulaChars&&o.startsWith("\t"))for(const e of FORMULA_TRIGGER_CHARS)if(o.length>1&&o.charAt(1)===e)return o.substring(1);return o}function _convertToExcelDateFormatString(e){switch(e){case DateFormat.DATE_SHORT:return"dd/MM/yyyy";case DateFormat.DATE_LONG:return"MMMM d, yyyy";case DateFormat.TIME_SHORT:return"h:mm AM/PM";case DateFormat.TIME_LONG:return"h:mm:ss AM/PM";case DateFormat.DATE_TIME_SHORT:case DateFormat.DEFAULT:return"MMM d yyyy h:mm AM/PM";case DateFormat.DATE_TIME_LONG:return"MMMM d yyyy h:mm AM/PM";case DateFormat.FULL:return"dddd, MMMM d yyyy h:mm AM/PM";case DateFormat.ISO_8601:case DateFormat.ROUND_TRIP:return'yyyy-MM-dd"T"HH:mm:ss';default:{const t=e.replace(/tt/g,"AM/PM");return t.includes("z")&&_getConvertLogger().warn("Warning: Excel will not recognize timezone format 'z', 'zz', or 'zzz'"),t.includes("h")&&!t.includes("AM/PM")&&_getConvertLogger().warn("Warning: Excel will interpret 'h' as 'H' if the format does not have an AM/PM designator"),t}}}function _convertToExcelNumberFormatString(e){switch(e){case NumberFormat.ACCOUNTING:return'_("$"* #,##0.00_);_("$"* (#,##0.00);_("$"* "-"??_);_(@_)';case NumberFormat.CURRENCY:return'"$"#,##0.00';case NumberFormat.FIXED_POINT:case NumberFormat.DEFAULT:return"0.0000";case NumberFormat.NUMBER:return"#,##0.0000";case NumberFormat.PERCENT:return"0%";case NumberFormat.ROUND_TRIP:return"0.00000";default:return e}}function _toXLSXValue(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}let r=e.toString();return t.escapeFormulaChars&&(r=escapeFormulaChars(r)),r}async function _parseXLSX(e,t){const r=await import("xlsx"),o=new Promise(((o,a)=>{const n=new FileReader;n.onload=()=>{const e=new Uint8Array(n.result);let a="";for(const t of e)a+=String.fromCharCode(t);const s=r.read(a,{type:"binary",cellDates:!0}),i=t.sheetName||s.SheetNames[0],m=s.Sheets[i];o(m)},n.onerror=()=>{a(n.error)},n.readAsArrayBuffer(e)})),a=await o,n=r.utils.decode_range(a["!ref"]),s=[];for(let e=n.s.r;e<=n.e.r;e++){const t=[];for(let o=n.s.c;o<=n.e.c;o++){const n=a[`${r.utils.encode_cell({r:e,c:o})}`];t.push(n?{raw:n.v,formatted:"s"===n.t?void 0:n.w}:{raw:""})}s.push(t)}return s}async function _getDBaseSpatialReferenceWKT(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??esriWkidToWkt(t??SpatialReference.WGS84.wkid)}function _getDBaseColumnTypes(e,t,r,o){const a={};for(const n of t){if(e.some((e=>_hasCodedDomain(e,n)))){a[n]=DBaseTypes.STRING;continue}const t=r?r.fields.find((e=>e.name===n)):void 0;if(t){switch(t.type){case"oid":case"double":case"integer":case"single":case"small-integer":a[n]=DBaseTypes.NUMBER;break;case"date":a[n]=o?DBaseTypes.NUMBER:DBaseTypes.DATE;break;default:a[n]=DBaseTypes.STRING}continue}const s=(e,t)=>e.attributes.get(t)??e.presentableAttributes.get(t);e.every((e=>s(e,n)instanceof Date||void 0===s(e,n)))&&e.some((e=>s(e,n)instanceof Date))?a[n]=o?DBaseTypes.NUMBER:DBaseTypes.DATE:e.every((e=>"number"==typeof s(e,n)||void 0===s(e,n)))&&e.some((e=>"number"==typeof s(e,n)))?a[n]=DBaseTypes.NUMBER:e.every((e=>"boolean"==typeof s(e,n)||void 0===s(e,n)))&&e.some((e=>"boolean"==typeof s(e,n)))?a[n]=DBaseTypes.BOOLEAN:a[n]=DBaseTypes.STRING}return a}function _getDBaseGeometries(e){return e.map((e=>{if(isPoint(e)){const{x:t,y:r,z:o,m:a}=e,n=[t,r];return e.hasZ&&n.push(o),e.hasM&&n.push(a),_padZValues(n,e)}if(isMultipoint(e))return _padZValuesArray(e.points,e);if(isPolyline(e))return _padZValues2DArray(e.paths,e);if(isPolygon(e))return _padZValues2DArray(e.rings,e);if(isExtent(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.")}))}function _padZValues(e,t){return 3===e.length&&!t.hasZ&&t.hasM?[e[0],e[1],void 0,e[2]]:e}function _padZValuesArray(e,t){return e.map((e=>_padZValues(e,t)))}function _padZValues2DArray(e,t){return e.map((e=>_padZValuesArray(e,t)))}function _getDbaseValues(e,t,r,o){const a=[];for(const n of e){const e={};for(const a of t){let t=_getAttributeValue(n,a,o);if(null==t&&(t=""),o.useFormattedValues)t=t.toString();else{t=getDbaseValue(t,r[a],o)}e[a]=t}a.push(e)}return a}function getDbaseValue(e,t,r){switch(t){case DBaseTypes.NUMBER:return e instanceof Date?e.getTime():parseNumber(e);case DBaseTypes.STRING:return e instanceof Date?formatDate({format:r.dateFormat??DateFormat.ROUND_TRIP,timeZone:"UTC"},e):"number"==typeof e?formatNumber(r.numberFormat??NumberFormat.DEFAULT,e):e.toString();case DBaseTypes.BOOLEAN:return!!e;case DBaseTypes.DATE:return parseDate(e);default:return e.toString()}}function _parseShapefileNames(e){if(!e.length)return[];let t=e[0];const r=t.match(shapefileNameRegex);return r?(t=r[1],e.filter((e=>{const r=e.match(shapefileNameRegex);return r&&r[1]===t}))):[t]}function _parseDBaseData(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]})))))]}function _parseShpPointGeometry(e){checkArg("geometry.coordinates",e.type).matches("Point"),checkArg("geometry.coordinates",e.coordinates).satisfies((e=>"number"==typeof e||Array.isArray(e)));const[t,r,o]=e.coordinates,a=new Point({x:t,y:r,spatialReference:SpatialReference.WGS84});if(Array.isArray(o)){const[e,t]=o;!e&&!t||e?a.z=e:a.m=t}return a}async function _parseShpGeometry(e,t){const r=isPoint(e)?_parseShpPointGeometry(e):geoJSONToEsri(e);if(t){let e;try{const r=await esriWktToWkid(t);e=new SpatialReference({wkid:parseNumber(r)})}catch{}e||(e=new SpatialReference({wkt:t})),r.spatialReference=e}return r}
|