UNPKG

@arcgis/core

Version:

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

3 lines (2 loc) • 13.2 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */ import{__decorate as e}from"tslib";import t from"../../Camera.js";import i from"../../Ground.js";import o from"../../Map.js";import a from"../../core/Collection.js";import r from"../../core/Error.js";import{EventedAccessor as s}from"../../core/Evented.js";import{addEventListener as n}from"../../core/events.js";import{JSONMap as d}from"../../core/jsonMap.js";import h from"../../core/Logger.js";import{rad2deg as l,deg2rad as m}from"../../core/mathUtils.js";import{destroyMaybe as c}from"../../core/maybe.js";import{waitTick as p}from"../../core/promiseUtils.js";import{watch as u,syncAndInitial as g,when as v,whenOnce as _}from"../../core/reactiveUtils.js";import{property as y,subclass as f}from"../../core/accessorSupport/decorators.js";import{UpdatingHandles as w}from"../../core/support/UpdatingHandles.js";import V from"../../geometry/SpatialReference.js";import M from"../../layers/GraphicsLayer.js";import{convertSphereVertexToPixelLocation as H}from"../../layers/orientedImagery/transformations/utils.js";import R from"../../views/SceneView.js";import{fixedImageSize as z}from"../OrientedImageryViewer/constants.js";import{createPanoramicMedia as b,extractHorizonAnglesFromMedia as P,logAndThrow as F,getMissingPropertyErrorName as S,getMissingPropertyErrorMessage as C}from"../OrientedImageryViewer/utils.js";import{defaultImageSphereCenter as j,maxPanoramicViewerHFOV as O,minPanoramicViewerHFOV as x,humanBinocularHFOV as I}from"./constants.js";import k from"./PanoramicZoomConditions.js";import A from"./PanoramicZoomViewModel.js";import{findDiagonalFOV as L,meshToGraphic as G,createImageSphere as T}from"./utils.js";import{enumeration as D}from"../../core/accessorSupport/decorators/enumeration.js";const E={default:"default",navigation:"navigation",fovConstraint:"fov-constraint",clickAction:"image-click-action",videoHandles:"video-handles"};let W=class extends s{constructor(e){super(e),this._startPosition=null,this._targetPosition=null,this._graphics=new M({elevationInfo:{mode:"relative-to-ground"}}),this._imageGraphic=null,this._loadController=null,this._map=new o({ground:new i({opacity:0,navigationConstraint:null}),layers:new a([this._graphics])}),this._zoomViewModel=null,this.autoLoad=!1,this.clickAction="none",this.closestFeature=null,this.currentTime=0,this.imageSize=null,this.media=null,this.oiViewModel=null,this.videoSource=null,this.videoDuration=void 0,this.videoLoaded=!1,this.videoPaused=null,this.videoMuted=null,this.pitch=90,this.state="ready",this.updatingHandles=new w,this.video=null,this.yaw=0,this._addNavigationHandles=()=>{this.imageRenderer.basemapTerrain.suspended=!0,this.imageRenderer.constraints.tilt.max=180,this.removeHandles(E.navigation),this.addHandles([this.imageRenderer.on("mouse-wheel",this._handleWheel),this.imageRenderer.on("double-click",this._handleDoubleClick),this.imageRenderer.on("drag",this._handleDrag),this.imageRenderer.on("key-down",e=>{const t=["+","-","Shift","_","=","ArrowUp","ArrowDown","ArrowRight","ArrowLeft"],i=e.key;t.includes(i)&&e.stopPropagation()})],E.navigation)},this._addHFOVHandles=()=>{this.removeHandles(E.fovConstraint),this.addHandles(u(()=>[this.maxHFOV,this.minHFOV],()=>{this._zoomViewModel&&(this._zoomViewModel.panoramicZoomConditions=new k({view:this.imageRenderer,maxFOV:this.maxHFOV,minFOV:this.minHFOV}))},g),E.fovConstraint)},this._addZoomHandles=()=>{this._zoomViewModel=new A({view:this.imageRenderer,panoramicZoomConditions:new k({maxFOV:this.maxHFOV,minFOV:this.minHFOV})});const e=this.imageRenderer.ui.find("zoom");e&&(e.viewModel=this._zoomViewModel),this._addHFOVHandles()},this._cancelLoadWithController=()=>{this._loadController?.abort(),this._loadController=null},this._createMedia=(e,t)=>{this.media=b({type:"video",url:e,matrix:t.attributes.matrix,cameraHeading:t.attributes.cameraHeading})},this._handleDoubleClick=e=>{e.stopPropagation(),e.native.ctrlKey?this._zoomOut():this._zoomIn()},this._handleDrag=e=>{e.stopPropagation();const{action:t,x:i,y:o}=e;switch(t){case"start":this._startPosition=this._targetPosition={x:i,y:o};break;case"update":this._targetPosition={x:i,y:o},this._updateCameraHeadingAndTilt()}},this._handleImageClick=e=>{if("image-loaded"===this.state&&this.imageRenderer.ready)switch(this.clickAction){case"emit":e.stopPropagation(),this.emit("click",e);break;case"hittest":e.stopPropagation(),e.defer(async()=>{const t=await this.imageRenderer.hitTest(e.screenPoint,{include:this._graphics});t.results=t.results.filter(e=>"graphic"===e.type&&e.graphic!==this._imageGraphic),this.emit("hittest-response",t)});break;case"pixel-location":{if(e.stopPropagation(),!this.imageSize||!e.mapPoint)return void this.emit("pixel-location",null);const t=H(e.mapPoint,this.imageSize[0],this.imageSize[1]);this.emit("pixel-location",{...t,spatialReference:V.WebMercator});break}}},this._handleWheel=e=>{const t=e.deltaX??e.native.deltaX;e.stopPropagation(),t>0||e.deltaY>0?this._zoomOut():this._zoomIn()},this._loadWithController=()=>{this._cancelLoadWithController(),this._loadController=new AbortController,this.loadVideo(this._loadController)},this._updateMedia=(e,t,i)=>{i.url=e,i.matrix=t.attributes.matrix,i.cameraHeading=t.attributes.cameraHeading},this._zoomIn=()=>this._zoomViewModel?.zoomIn(),this._zoomOut=()=>this._zoomViewModel?.zoomOut(),this.addGraphic=(e,t)=>"image-loaded"===this.state&&!this._graphics.graphics.includes(e)&&(this._graphics.graphics.add(e,t),!0),this.addManyGraphics=e=>{if("image-loaded"!==this.state)return!1;const t=e.filter(e=>!this._graphics.graphics.includes(e));return this._graphics.graphics.addMany(t),!0},this.clearGraphics=()=>{this._graphics.graphics.removeAll()},this.clearImage=()=>{this.imageSize=null,this._removeImageSphere()},this.enableAudio=()=>{const{video:e}=this;e&&(e.muted=!1,this.videoMuted=!1)},this.removeGraphic=e=>!("image-loaded"!==this.state||!this._graphics.graphics.includes(e))&&(this._graphics.remove(e),!0),this.removeManyGraphics=e=>{if("image-loaded"!==this.state)return!1;const t=e.filter(e=>this._graphics.graphics.includes(e));return this._graphics.removeMany(t),!0},this.togglePanoramicAudio=()=>{if(this.video){const e=this.video.muted;this.video.muted=!e,this.videoMuted=!e}},this._imageRenderer=new R({map:this._map,viewingMode:"local",camera:{position:j},environment:{atmosphereEnabled:!1,starsEnabled:!1,lighting:{type:"virtual"}},popupEnabled:!1,spatialReference:V.WebMercator,attributionVisible:!1,ui:{components:["zoom"]}})}destroy(){this._imageRenderer.destroy()}initialize(){this.state="initialized",this.addHandles([u(()=>this.videoSource,()=>{this.videoSource&&this.autoLoad&&this._loadWithController()},g),u(()=>this.fov,()=>{this._reloadCamera()},g),u(()=>this.yaw,e=>{this.camera&&(this.camera.heading=e,this._reloadCamera())},g),u(()=>this.pitch,e=>{this.camera&&(this.camera.tilt=e,this._reloadCamera())},g),v(()=>this.imageRenderer.ready,()=>{this._addNavigationHandles(),this._addZoomHandles()},g),u(()=>this.clickAction,e=>{this.removeHandles(E.clickAction),"none"!==e&&this.addHandles(this.imageRenderer.on("click",this._handleImageClick))},g),u(()=>this.video,e=>{if(e instanceof HTMLVideoElement){this._startVideo();const t=async()=>{this.currentTime=Number(e.currentTime.toFixed(2)),e.currentTime&&await this._updateVidFootprint(e.currentTime)};this.removeHandles(E.videoHandles);const i=n(e,"timeupdate",t),o=n(e,"play",()=>this._updateVideoIcon(e.paused)),a=n(e,"pause",()=>this._pauseVideoHandler(e));this.addHandles([i,o,a],E.videoHandles)}},g),u(()=>[this.videoSource,this.oiViewModel?.currentBestFeature,this.closestFeature],()=>{if(!this.videoSource||!this.oiViewModel.currentBestFeature)return;const e=this.closestFeature??this.oiViewModel.currentBestFeature;this.media?this._updateMedia(this.videoSource,e,this.media):this._createMedia(this.videoSource,e)},g)],E.default)}get camera(){return this.imageRenderer.destroying||this.imageRenderer.destroyed?null:this.imageRenderer.camera}set camera(e){!e||this.imageRenderer.destroying||this.imageRenderer.destroyed||(this.imageRenderer.camera=e.clone())}get fov(){return this.camera?.fov}set fov(e){Number.isFinite(e)&&this._zoomViewModel?.zoomTo(e)}get horizonAngles(){return P(this.media)}get hfov(){if(!this.camera||!this.imageRenderer?.ready)return null;const{fov:e}=this.camera,{size:[t,i]}=this.imageRenderer,o=t/i,a=Math.atan(o);return 2*l(Math.atan(Math.tan(m(e/2))*Math.sin(a)))}get imageRenderer(){return this._imageRenderer}get maxHFOV(){const{size:[e,t]}=this.imageRenderer;return this.imageRenderer.ready?L(O,e/t):O}get minHFOV(){const{size:[e,t]}=this.imageRenderer;return this.imageRenderer.ready?L(x,e/t):x}get updating(){return this.updatingHandles.updating}get vfov(){if(!this.camera||!this.imageRenderer?.ready)return null;const{fov:e}=this.camera,{size:[t,i]}=this.imageRenderer,o=t/i,a=Math.atan(o);return 2*l(Math.atan(Math.tan(m(e/2))*Math.cos(a)))}async _loadVideoInternal(e,t){return this.state="image-loading",this.video=document.createElement("video"),this.video.src=e,this.video.addEventListener("loadedmetadata",()=>{this._setVideoDuration(),this.videoLoaded=!0}),this._updateImageSphere(this.video,t)}_pauseVideoHandler(e){this._updateVideoIcon(e.paused)}_setVideoDuration(){const{video:e}=this;e?.duration&&(this.videoDuration=e.duration)}_startVideo(){try{this.enableAudio();const e=this.oiViewModel.currentBestFeature;e&&this.playPanoramicVideoFromSelectedLocation(e)}catch(e){h.getLogger(this).error("oriented-imagery-viewer:video-load",e)}}_reloadCamera(){this.camera=this.camera?.clone()}_removeImageSphere(){this._imageGraphic&&(this._graphics.remove(this._imageGraphic),this._imageGraphic=c(this._imageGraphic)),this.state="ready",this.imageSize=null}_updateCameraHeadingAndTilt(){if(!this._startPosition||!this._targetPosition||!this.camera)return;const e=this.camera.heading+(this._startPosition.x-this._targetPosition.x)/this.imageRenderer.width*this.camera.fov;this.yaw=(e+360)%360;const t=this.camera.tilt-(this._startPosition.y-this._targetPosition.y)/this.imageRenderer.height*this.imageRenderer.camera.tilt;this.pitch=Math.min(179.5,Math.max(.5,t)),this._startPosition=this._targetPosition}async _updateImageSphere(e,t){await p(t);const[i,o,a]=this.horizonAngles??[0,0,0];return this._imageGraphic=G(T({data:e,horizonPitch:i,horizonRoll:o,horizonYaw:a})),this._graphics.add(this._imageGraphic),this.state="image-loaded",_(()=>this.imageRenderer.ready,t).then(()=>{const{size:[e,t]}=this.imageRenderer;this.fov=L(I,e/t)}),this.imageSize=z,this._imageGraphic.geometry}async _updateVidFootprint(e){const t=this.oiViewModel?.featureCache.find(t=>t.attributes.offsetFromStart===Math.floor(e)),{yaw:i,pitch:o,vfov:a,hfov:r}=this,s=!(t?.attributes.offsetFromStart&&a&&r&&i&&o),n=t?.attributes.objectId===this.closestFeature?.attributes.objectId;s||n||(this.closestFeature=t)}_updateVideoIcon(e){this.videoPaused=!!e}async loadVideo(e){return this._removeImageSphere(),this.videoSource?this._loadVideoInternal(this.videoSource,e):F(this.declaredClass,new r(S("panoramic-viewer"),C("PanoramicViewerViewModel","videoSource")))}playPanoramicVideoHandler(){const{video:e}=this;e&&(e.paused?e.play().catch(e=>{h.getLogger(this).error("error playing video",e)}):e.pause())}playPanoramicVideoFromSelectedLocation(e){const t=e.attributes.offsetFromStart;if(t){const e=this.video;e&&(e.currentTime=t,e.play().catch(e=>{h.getLogger(this).error("error playing video",e)}))}}rewindPanoramicVideoHandler(){const{video:e}=this;e&&(e.currentTime=0,e.play().catch(e=>{h.getLogger(this).error("error playing video",e)}))}};e([y()],W.prototype,"_graphics",void 0),e([y()],W.prototype,"_imageGraphic",void 0),e([y()],W.prototype,"_imageRenderer",void 0),e([y()],W.prototype,"_loadController",void 0),e([y()],W.prototype,"_map",void 0),e([y()],W.prototype,"_zoomViewModel",void 0),e([y({type:Boolean})],W.prototype,"autoLoad",void 0),e([y({type:t})],W.prototype,"camera",null),e([D(new d({emit:"emit",hittest:"hittest",none:"none","pixel-location":"pixel-location"}))],W.prototype,"clickAction",void 0),e([y()],W.prototype,"closestFeature",void 0),e([y()],W.prototype,"currentTime",void 0),e([y({type:Number})],W.prototype,"fov",null),e([y()],W.prototype,"horizonAngles",null),e([y({readOnly:!0})],W.prototype,"hfov",null),e([y({readOnly:!0})],W.prototype,"imageRenderer",null),e([y()],W.prototype,"imageSize",void 0),e([y()],W.prototype,"media",void 0),e([y()],W.prototype,"oiViewModel",void 0),e([y()],W.prototype,"videoSource",void 0),e([y()],W.prototype,"videoDuration",void 0),e([y()],W.prototype,"videoLoaded",void 0),e([y()],W.prototype,"videoPaused",void 0),e([y()],W.prototype,"videoMuted",void 0),e([y({readOnly:!0})],W.prototype,"maxHFOV",null),e([y({readOnly:!0})],W.prototype,"minHFOV",null),e([y({type:Number})],W.prototype,"pitch",void 0),e([y()],W.prototype,"state",void 0),e([y()],W.prototype,"updatingHandles",void 0),e([y()],W.prototype,"updating",null),e([y({readOnly:!0})],W.prototype,"vfov",null),e([y()],W.prototype,"video",void 0),e([y({type:Number})],W.prototype,"yaw",void 0),W=e([f("esri.widgets.PanoramicViewer.PanoramicVideoViewerViewModel")],W);const N=W;export{N as default};