UNPKG

@arcgis/core

Version:

ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API

6 lines (5 loc) 5.99 kB
/* All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://js.arcgis.com/4.33/esri/copyright.txt for details. */ import{_ as e}from"../../../../chunks/tslib.es6.js";import t from"../../../../request.js";import r from"../../../../core/Error.js";import i from"../../../../core/Logger.js";import{createResolver as o}from"../../../../core/promiseUtils.js";import{addQueryParameters as s}from"../../../../core/urlUtils.js";import"../../../../core/has.js";import"../../../../core/RandomLCG.js";import{subclass as n}from"../../../../core/accessorSupport/decorators/subclass.js";import a from"../../../../geometry/SpatialReference.js";import{fromJSON as c}from"../../../../geometry/support/jsonUtils.js";import{WebSocketConnection as u}from"./WebSocketConnection.js";import{executeQuery as l}from"../../../../rest/query/operations/query.js";import f from"../../../../rest/support/Query.js";const h=1e4,d={maxQueryDepth:5,maxRecordCountFactor:3};let g=class extends u{constructor(e){super({...d,...e}),this._buddyServicesQuery=null,this._relatedFeatures=null}async _open(){const e=await this._fetchServiceDefinition(this._config.source);e.timeInfo.trackIdField||i.getLogger(this).warn("GeoEvent service was configured without a TrackIdField. This may result in certain functionality being disabled. The purgeOptions.maxObservations property will have no effect.");const t=this._fetchWebSocketUrl(e.streamUrls,this._config.spatialReference);this._buddyServicesQuery||(this._buddyServicesQuery=this._queryBuddyServices()),await this._buddyServicesQuery,await this._tryCreateWebSocket(t);const{filter:r,outFields:o}=this._config;this.destroyed||this._setFilter(r,o)}_onMessage(e){if("attributes"in e){let o;try{o=this._enrich(e),null!=this._featureZScaler&&this._featureZScaler(o.geometry)}catch(t){return void i.getLogger(this).error(new r("geoevent-connection","Failed to parse message",t))}this.onFeature(o)}else this.onMessage(e)}async _fetchServiceDefinition(e){const r={f:"json",...this._config.customParameters},i=t(e.path,{query:r,responseType:"json"}),o=(await i).data;return this._serviceDefinition=o,o}_fetchWebSocketUrl(e,t){const r=e[0],{urls:i,token:o}=r,n=this._inferWebSocketBaseUrl(i);return s(`${n}/subscribe`,{outSR:""+t.wkid,token:o})}_inferWebSocketBaseUrl(e){if(1===e.length)return e[0];for(const t of e)if(t.includes("wss"))return t;return i.getLogger(this).error(new r("geoevent-connection","Unable to infer WebSocket url",e)),null}async _setFilter(e,t){const s=this._websocket;if(null==s||null==e&&null==t)return;const n=JSON.stringify({filter:this._serializeFilter(e,t)});let a=!1;const c=o(),u=()=>{a||(this.destroyed||this._websocket!==s||i.getLogger(this).error(new r("geoevent-connection","Server timed out when setting filter")),c.reject())},l=e=>{const t=JSON.parse(e.data);t.filter&&(t.error&&(i.getLogger(this).error(new r("geoevent-connection","Failed to set service filter",t.error)),this._set("errorString",`Could not set service filter - ${t.error}`),c.reject(t.error)),this._setWebSocketJSONParseHandler(s),a=!0,c.resolve())};return s.onmessage=l,s.send(n),setTimeout(u,h),c.promise}_serializeFilter(e,t){const o={};if(null==e&&null==t)return o;if(e?.geometry)try{const t=c(e.geometry);if("extent"!==t.type)throw new r("geoevent-connection",`Expected extent but found type ${t.type}`);o.geometry=JSON.stringify(t.shiftCentralMeridian())}catch(s){i.getLogger(this).error(new r("geoevent-connection","Encountered an error when setting connection geometryDefinition",s))}return e?.where&&"1 = 1"!==e.where&&"1=1"!==e.where&&(o.where=e.where),null!=t&&(o.outFields=t.join(",")),o}_enrich(e){if(!this._relatedFeatures)return e;const t=this._serviceDefinition.relatedFeatures.joinField,o=e.attributes[t],s=this._relatedFeatures.get(o);if(!s)return i.getLogger(this).warn("geoevent-connection","Feature join failed. Is the join field configured correctly?",e),e;const{attributes:n,geometry:a}=s;for(const r in n)e.attributes[r]=n[r];return a&&(e.geometry=a),e.geometry||e.centroid||i.getLogger(this).error(new r("geoevent-connection","Found malformed feature - no geometry found",e)),e}async _queryBuddyServices(){try{const{relatedFeatures:e,keepLatestArchive:t}=this._serviceDefinition,r=this._queryRelatedFeatures(e),i=this._queryArchive(t);await r;const o=await i;if(!o)return;for(const s of o.features)this.onFeature(this._enrich(s))}catch(e){i.getLogger(this).error(new r("geoevent-connection","Encountered an error when querying buddy services",{error:e}))}}async _queryRelatedFeatures(e){if(!e)return;const t=await this._queryBuddy(e.featuresUrl);this._addRelatedFeatures(t)}async _queryArchive(e){if(e)return this._queryBuddy(e.featuresUrl)}async _queryBuddy(e){const t=new((await import("../../../FeatureLayer.js")).default)({url:e}),{capabilities:r}=await t.load(),i=r.query.supportsMaxRecordCountFactor,o=r.query.supportsPagination,s=r.query.supportsCentroid,n=this._config.maxRecordCountFactor,c=t.capabilities.query.maxRecordCount,u=i?c*n:c,h=new f;if(h.outFields=this._config.outFields??["*"],h.where=this._config.filter?.where??"1=1",h.returnGeometry=!0,h.returnExceededLimitFeatures=!0,h.outSpatialReference=a.fromJSON(this._config.spatialReference),s&&(h.returnCentroid=!0),i&&(h.maxRecordCountFactor=n),o)return h.num=u,t.destroy(),this._queryPages(e,h);const d=await l(e,h,this._config.sourceSpatialReference);return t.destroy(),d.data}async _queryPages(e,t,r=[],i=0){t.start=null!=t.num?i*t.num:null;const{data:o}=await l(e,t,this._config.sourceSpatialReference);return o.exceededTransferLimit&&i<(this._config.maxQueryDepth??0)?(o.features.forEach((e=>r.push(e))),this._queryPages(e,t,r,i+1)):(r.forEach((e=>o.features.push(e))),o)}_addRelatedFeatures(e){const t=new Map,r=e.features,i=this._serviceDefinition.relatedFeatures.joinField;for(const o of r){const e=o.attributes[i];t.set(e,o)}this._relatedFeatures=t}};g=e([n("esri.layers.graphics.sources.connections.GeoEventConnection")],g);export{g as default};