@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 12.1 kB
JavaScript
/*
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"../../core/Collection.js";import r from"../../core/Error.js";import i from"../../core/Evented.js";import o from"../../core/Logger.js";import{debounce as s,isAbortError as a}from"../../core/promiseUtils.js";import{watch as l,on as n,syncAndInitial as u,when as d}from"../../core/reactiveUtils.js";import{property as c}from"../../core/accessorSupport/decorators/property.js";import"../../core/has.js";import"../../core/RandomLCG.js";import{subclass as h}from"../../core/accessorSupport/decorators/subclass.js";import{resolveTimeZone as p,formatTimestamp as m,convertDateFormatToIntlOptions as v}from"../../intl/date.js";import{getLocale as y,getLocaleParts as f}from"../../intl/locale.js";import{fetchServiceDescription as g}from"../../rest/networkService.js";import w from"../../rest/support/RouteParameters.js";import _ from"../../rest/support/Stop.js";import T from"../../rest/support/TravelMode.js";import{defaultDatePattern as S,defaultTimePattern as D}from"../../support/dateUtils.js";import{system as C}from"../../time/constants.js";import{shortTimeZoneName as b}from"../../time/timeZoneUtils.js";import{DepartureTimeOption as M}from"./support/directionsUtils.js";import{getDefaultLocaleOptions as A}from"../support/dateUtils.js";import I from"../support/GoTo.js";import{DateTime as j,FixedOffsetZone as L,IANAZone as R}from"luxon";function E(e){return e.map((e=>({locale:e,parts:f(e)}))).filter((({parts:e})=>!!e))}function P(e,t){return e.find((({parts:e})=>F(e.language,t.language)&&e.region===t.region))?.locale??e.find((({parts:e})=>F(e.language,t.language)))?.locale}function U(e){return"esri.Graphic"===e?.declaredClass}function N(e){return"no"===e||"nb"===e}function F(e,t){return e===t||N(e)&&N(t)}function O(e){return"esri.rest.support.Stop"===e?.declaredClass}var k;!function(e){e[e.Active=0]="Active",e[e.Complete=1]="Complete",e[e.Failed=2]="Failed",e[e.Idle=3]="Idle",e[e.Suspended=4]="Suspended"}(k||(k={}));let V=class extends(I(i.EventedAccessor)){constructor(e){super(e),this._debouncedSolveHandler=s((async e=>{switch(e.type){case"create":if("complete"!==e.state)return;break;case"delete":break;case"update":switch(e.state){case"start":return void(this._networkFeatureUpdated=!1);case"active":return void(this._networkFeatureUpdated=!0);case"complete":if(!this._networkFeatureUpdated)return}}if(!((this.layer?.stops.filter((({geometry:e})=>!!e)).length??0)<2)&&this.autoSolve)try{await this.getDirections({zoomToSolvedRoute:!1})}catch(t){o.getLogger(this).error(t)}})),this._highlight=null,this._loadController=null,this._loadPromise=null,this._networkFeatureUpdated=!1,this._layerView=null,this._routeController=null,this._serviceDescriptionStatus=k.Idle,this.apiKey=void 0,this.autoSolve=!0,this.defaultTravelMode=null,this.departureIsoDate=void 0,this.departureIsoTime=void 0,this.departureOption=M.NOW,this.departureTime="now",this.lastError=null,this.lastRoute=null,this.layer=null,this.maxStops=50,this.routeParameters=new w({directionsLengthUnits:"kilometers",findBestSequence:!1,preserveFirstStop:!0,preserveLastStop:!0,returnZ:!0,useTimeWindows:!1}),this.serviceDescription=null,this.view=null}initialize(){this.addHandles([l((()=>this.layer),(e=>{if(null!=e){for(;e.stops.length<2;)e.stops.add(new _);this._set("defaultTravelMode",null),this.addHandles(d((()=>this.serviceDescription?e.routeInfo?.analysisSettings?.travelMode:null),(e=>{this.defaultTravelMode=this._resolveDefaultTravelMode(e)}),{once:!0}))}}),u),l((()=>[this.layer,this.view]),(async()=>{this._layerView=await this._getRouteLayerView()}),u),n((()=>this._layerView),["create","delete","update"],(e=>{this._debouncedSolveHandler(e).catch((e=>{if(!a(e))throw e}))}))]);const e=p(this.view?.timeZone??C),t=j.fromMillis(Date.now());this.departureIsoDate=t.toFormat(S,A(e)),this.departureIsoTime=t.toFormat(D,A(e))}get _directionsLanguage(){const e=this.serviceDescription?.directionsSupportedLanguages;if(!e)return;const t=this.routeParameters.directionsLanguage??y(),r=f(t),i=r?.language,o=r?.region;if(!i)return;return P(E(e),{language:i,region:o})}get formattedEta(){const e=this.layer?.routeInfo?.endTime,t=this.layer?.routeInfo?.endTimeOffset;if(this.departureOption===M.UNSPECIFIED||!e||!t)return null;const r=j.fromJSDate(e,{zone:L.instance(t)}),i=j.fromJSDate(e,{zone:R.create(p(this.view?.timeZone??C))}),o=j.fromJSDate(new Date,{zone:R.create(p(this.view?.timeZone??C))}),s=o.year===i.year&&o.month===i.month&&o.day===i.day,a=i.offset===t?void 0:b,l=s?void 0:v("short-date"),n=v("short-time");return m(r.toISO(),{...l,...n,timeZoneName:a})}get impedanceAttribute(){const e=this.routeParameters.travelMode?.impedanceAttributeName??this.routeParameters.impedanceAttribute??this.serviceDescription?.impedance??null;return this.getCostAttribute(e)}get selectedNetworkFeatures(){return this._layerView?.selectedNetworkFeatures??null}get selectedTravelMode(){return this.serviceDescription?this.defaultTravelMode??this.serviceDescription.defaultTravelMode??this.serviceDescription.supportedTravelModes?.[0]??null:null}set selectedTravelMode(e){this._override("selectedTravelMode",e)}get state(){if(this._routeController)return"routing";if(this.lastError)return"error";switch(this._serviceDescriptionStatus){case k.Suspended:return"unauthenticated";case k.Idle:return"disabled";case k.Active:return"initializing";case k.Failed:return"error";default:return"ready"}}get timeAttribute(){const e=this.routeParameters.travelMode?.timeAttributeName??this.routeParameters.directionsTimeAttribute??this.serviceDescription?.directionsTimeAttribute??null;return this.getCostAttribute(e)}get travelModes(){const e=this.serviceDescription?.supportedTravelModes?.slice()??[];return null==this.defaultTravelMode||e.includes(this.defaultTravelMode)||e.unshift(this.defaultTravelMode),e}async load(){if(this._loadPromise)return this._loadPromise;this._loadPromise=this._load(),await this._loadPromise,this._loadPromise=null}async highlight(e){if(this.clearHighlights(),!this.view||!this.layer)return;const t=await this.view.whenLayerView(this.layer);this._highlight=t.highlight(e)}clearHighlights(){null!=this._highlight&&(this._highlight.remove(),this._highlight=null)}centerAt(e){if(!this.view)return;const t=O(e)||U(e)?e.geometry:e;t&&this.callGoTo({target:t})}clearResults(){this._set("lastRoute",null),this.layer?.removeResult()}async create(e){await(this._layerView?.create(e))}async getDirections(e={zoomToSolvedRoute:!0}){const{apiKey:t,layer:i,state:o}=this;if(!i)throw new r("directions-view-model:missing-route-layer","A route layer must be associated with the view model.");if("unauthenticated"===o||"initializing"===o||"disabled"===o||this._serviceDescriptionStatus===k.Failed)throw new r("directions-view-model:not-loaded","Cannot get directions until view model loads.");null!=this._routeController&&(this._routeController.abort(),this._routeController=null);const{startTime:s,startTimeIsUTC:l}=this._getStartTimeParameters(),n=this.view?.spatialReference??null,u=this.routeParameters.clone();u.set({apiKey:t,directionsLanguage:this._directionsLanguage,outSpatialReference:n,startTime:s,startTimeIsUTC:l}),this.selectedTravelMode&&(u.travelMode=this.selectedTravelMode);if(i.stops.filter((({geometry:e})=>null!=e)).length<2){const e=new r("directions-view-model:not-enough-stops","Not enough stops for routing");throw this._set("lastError",e),e}i.stops.forEach((e=>e.sequence=null)),this._routeController=new AbortController;const{signal:d}=this._routeController;let c=null;try{c=await i.solve(u,{signal:d})}catch(h){if(!a(h)){const e=new r("directions-view-model:unable-to-route","Unable to route to these addresses",{error:h});throw this._set("lastError",e),this.clearResults(),e}}finally{this._routeController=null}this._set("lastError",null);for(const r of c.stops)null==r.geometry&&(r.name=null);return i.update(c),this._set("lastRoute",c),e.zoomToSolvedRoute&&this.zoomToRoute(),c}getCostAttribute(e){return(this.serviceDescription?.networkDataset?.networkAttributes??[]).find((({name:t,usageType:r})=>t===e&&"cost"===r))??null}remove(e){this._layerView?.remove(e)}reset(){this.clearHighlights(),this.clearResults(),null!=this.layer&&(this.layer.removeAll(),this.layer.stops=new t([new _,new _]))}save(){if(!this.layer)throw new r("directions-view-model:missing-layer","save() requires a layer");return this.layer.save()}saveAs(e,t={}){if(!this.layer)throw new r("directions-view-model:missing-layer","saveAs() requires a layer");return this.layer.saveAs(e,t)}async startEditing(){this._layerView&&(this._layerView.interactive=!0)}async stopEditing(){this._layerView&&(this._layerView.interactive=!1)}updateDepartureTime(){if(this.departureIsoDate&&this.departureIsoTime)switch(this.departureOption){case M.NOW:this.departureTime="now";break;case M.DEPART_AT:{const e=j.fromISO(`${this.departureIsoDate}T${this.departureIsoTime}`,{zone:L.instance(0)});this.departureTime=e.toJSDate();break}case M.UNSPECIFIED:this.departureTime=null}}zoomToRoute(){const{view:e,layer:t}=this,r=t?.routeInfo?.geometry?.extent;if(!e||!r)return;const i=r.width>r.height,o=r.clone().expand(i?2:1);this.callGoTo({target:o})}async _getRouteLayerView(){return this.view&&this.layer?this.view.whenLayerView(this.layer):null}_getStartTimeParameters(){if("now"===this.departureTime){return{startTime:this.serviceDescription?.capabilities.supportsNow??!1?"now":new Date,startTimeIsUTC:!0}}return null==this.departureTime?{startTime:void 0,startTimeIsUTC:void 0}:{startTime:this.departureTime,startTimeIsUTC:!1}}async _load(){if(null==this.layer)return;null!=this._loadController&&(this._loadController.abort(),this._loadController=null),this._loadController=new AbortController;const{signal:e}=this._loadController;try{this._serviceDescriptionStatus=k.Active;const t=await g(this.layer.url,this.apiKey,{signal:e});this._set("serviceDescription",t),this._serviceDescriptionStatus=k.Complete}catch(t){if(a(t))return void(this._serviceDescriptionStatus=k.Idle);if("identity-manager:user-aborted"===t.name)return void(this._serviceDescriptionStatus=k.Suspended);const e=new r("directions-view-model:service-metadata-unavailable","Cannot load route service metadata",{error:t});throw this._serviceDescriptionStatus=k.Failed,this._set("lastError",e),e}finally{this._loadController=null}}_resolveDefaultTravelMode(e){if(null==this.serviceDescription)return null;const{defaultTravelMode:t,supportedTravelModes:r}=this.serviceDescription,i=/^<(?<name>.*)>$/i.exec(e.name)?.groups?.name;if(i){const o=r?.find((({name:e})=>e.toLocaleLowerCase()===i.trim().toLocaleLowerCase())),s=o??t;return T.fromJSON({...s?.toJSON(),...e.toJSON()})}const o=r?.find((({name:t})=>t.toLocaleLowerCase()===e.name.toLocaleLowerCase()));return o??t}};e([c()],V.prototype,"_directionsLanguage",null),e([c()],V.prototype,"_layerView",void 0),e([c()],V.prototype,"_routeController",void 0),e([c()],V.prototype,"_serviceDescriptionStatus",void 0),e([c()],V.prototype,"apiKey",void 0),e([c()],V.prototype,"autoSolve",void 0),e([c()],V.prototype,"defaultTravelMode",void 0),e([c()],V.prototype,"departureTime",void 0),e([c()],V.prototype,"formattedEta",null),e([c({readOnly:!0})],V.prototype,"impedanceAttribute",null),e([c()],V.prototype,"lastError",void 0),e([c({readOnly:!0})],V.prototype,"lastRoute",void 0),e([c()],V.prototype,"layer",void 0),e([c({type:Number,range:{min:2,max:50},nonNullable:!0})],V.prototype,"maxStops",void 0),e([c({type:w,nonNullable:!0})],V.prototype,"routeParameters",void 0),e([c({readOnly:!0})],V.prototype,"selectedNetworkFeatures",null),e([c({type:T})],V.prototype,"selectedTravelMode",null),e([c({readOnly:!0})],V.prototype,"serviceDescription",void 0),e([c({readOnly:!0})],V.prototype,"state",null),e([c({readOnly:!0})],V.prototype,"timeAttribute",null),e([c()],V.prototype,"travelModes",null),e([c()],V.prototype,"view",void 0),e([c()],V.prototype,"zoomToRoute",null),V=e([h("esri.widgets.Directions.DirectionsViewModel")],V);const z=V;export{z as default};