@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
3 lines (2 loc) • 12.3 kB
JavaScript
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */
import{__decorate as e}from"tslib";import i from"../../Camera.js";import t from"../../Ground.js";import a from"../../Map.js";import{createTask as r}from"../../core/asyncUtils.js";import s from"../../core/Collection.js";import o from"../../core/Error.js";import{EventedAccessor as n}from"../../core/Evented.js";import{JSONMap as h}from"../../core/jsonMap.js";import{rad2deg as m,deg2rad as d}from"../../core/mathUtils.js";import{abortMaybe as l}from"../../core/maybe.js";import{throwIfAborted as c}from"../../core/promiseUtils.js";import{watch as p,syncAndInitial as g,when as u,whenOnce as y}from"../../core/reactiveUtils.js";import{property as _,subclass as v}from"../../core/accessorSupport/decorators.js";import{UpdatingHandles as f}from"../../core/support/UpdatingHandles.js";import w from"../../geometry/SpatialReference.js";import M from"../../layers/GraphicsLayer.js";import{convertSphereVertexToPixelLocation as P}from"../../layers/orientedImagery/transformations/utils.js";import{isGraphic as R}from"../../support/graphicInstanceUtils.js";import C from"../../views/SceneView.js";import{extractHorizonAnglesFromMedia as z}from"../OrientedImageryViewer/utils.js";import{defaultImageSphereCenter as V,defaultImageSphereSize as H,maxPanoramicViewerHFOV as k,minPanoramicViewerHFOV as G,humanBinocularHFOV as O}from"./constants.js";import b from"./PanoramicZoomConditions.js";import j from"./PanoramicZoomViewModel.js";import{meshToGraphic as x,findDiagonalFOV as A}from"./utils.js";import I from"./support/PanoramicMedia.js";import{enumeration as S}from"../../core/accessorSupport/decorators/enumeration.js";const F={default:"default",navigation:"navigation",fovConstraint:"fov-constraint",clickAction:"image-click-action"};let L=class extends n{constructor(e){super(e),this._panTask=null,this._startPosition=null,this._targetPosition=null,this.tileCache=new Set,this._graphics=new M({elevationInfo:{mode:"relative-to-ground"}}),this._imageGraphic=null,this.currentGraphics=new s,this.imagePyramid=null,this.imagePyramidLevel=-1,this._map=new a({ground:new t({opacity:0,navigationConstraint:null}),layers:new s([this._graphics])}),this._imageRenderer=new C({map:this._map,viewingMode:"local",camera:{position:V},environment:{atmosphereEnabled:!1,starsEnabled:!1,lighting:{type:"virtual"}},popupEnabled:!1,spatialReference:w.WebMercator,attributionVisible:!1,ui:{components:["zoom"]}}),this._loadController=null,this.zoomViewModel=new j({panoramicViewerViewModel:this,view:this._imageRenderer,panoramicZoomConditions:new b({})}),this.autoLoad=!1,this.clickAction="none",this.imageMeshDistance=H/2,this.imageSize=null,this.pitch=90,this.state="ready",this.updatingHandles=new f,this.yaw=0,this._addNavigationHandles=(e=!0)=>{this.imageRenderer.basemapTerrain.suspended=!0,this.removeHandles(F.navigation);const i=[this.imageRenderer.on("mouse-wheel",this._handleWheel),this.imageRenderer.on("drag",this._handleDrag),this.imageRenderer.on("key-down",e=>{const i=["+","-","Shift","_","=","ArrowUp","ArrowDown","ArrowRight","ArrowLeft"],t=e.key;i.includes(t)&&e.stopPropagation()})];e&&i.push(this.imageRenderer.on("double-click",this._handleDoubleClick)),this.addHandles(i,F.navigation)},this._addHFOVHandles=()=>{this.removeHandles(F.fovConstraint),this.addHandles(p(()=>[this.maxHFOV,this.minHFOV],()=>{this.zoomViewModel&&(this.zoomViewModel.panoramicZoomConditions=new b({view:this.imageRenderer,maxFOV:this.maxHFOV,minFOV:this.minHFOV}))},g),F.fovConstraint)},this._addZoomHandles=()=>{this.zoomViewModel=new j({view:this.imageRenderer,panoramicZoomConditions:new b({maxFOV:this.maxHFOV,minFOV:this.minHFOV}),panoramicViewerViewModel:this});const e=this.imageRenderer.ui.find("zoom");e&&(e.viewModel=this.zoomViewModel),this._addHFOVHandles()},this._cancelLoadWithController=()=>{this._loadController=l(this._loadController)},this._createPanTask=()=>{this._panTask?.abort(),this._panTask=r(async e=>{if(!this.imagePyramid)return;const{hfov:i,vfov:t,yaw:a,pitch:r}=this,s=this.imagePyramid.getTiles(this.imagePyramidLevel,a,r,i,t).filter(e=>!this.tileCache.has(`${e.level}/${e.row}/${e.column}`));if(!s?.length)return;const o=await Promise.all(s.map(async i=>await i.loadMesh({signal:e})));c(e);const n=o.map(x);n.forEach((e,i)=>{const t=s[i].key;e.attributes={key:t},this.tileCache.add(t)}),this.addManyGraphics(n),this.currentGraphics.addMany(n),this._panTask=null})},this._handleDoubleClick=e=>{e.stopPropagation(),e.native.ctrlKey?this._zoomOut():this._zoomIn()},this._handleDrag=e=>{e.stopPropagation();const{action:i,x:t,y:a}=e;switch(i){case"start":this._startPosition=this._targetPosition={x:t,y:a};break;case"update":this._targetPosition={x:t,y:a},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 i=await this.imageRenderer.hitTest(e.screenPoint,{include:this._graphics}),t=Array.isArray(this._imageGraphic)?this._imageGraphic:[this._imageGraphic].filter(R);i.results=i.results.filter(e=>"graphic"===e.type&&!t.includes(e.graphic)),this.emit("hittest-response",i)});break;case"pixel-location":{if(e.stopPropagation(),!this.imageSize||!e.mapPoint||!this.media)return void this.emit("pixel-location",null);const i=z(this.media),t=P(e.mapPoint,this.imageSize[0],this.imageSize[1],i);this.emit("pixel-location",{...t,spatialReference:w.WebMercator});break}}},this._handleWheel=e=>{const i=e.deltaX??e.native.deltaX;e.stopPropagation(),i>0||e.deltaY>0?this._zoomOut():this._zoomIn()},this._loadWithController=()=>{this._cancelLoadWithController(),this.media&&(this._loadController=new AbortController,this._loadMediaInternal(this.media,this._loadController))},this._zoomIn=()=>{this.zoomViewModel?.zoomIn()},this._zoomOut=()=>{this.zoomViewModel?.zoomOut()},this.addGraphic=(e,i)=>"image-loaded"===this.state&&!this._graphics.graphics.includes(e)&&(this._graphics.graphics.add(e,i),!0),this.addManyGraphics=e=>{if("image-loaded"!==this.state)return!1;const i=e.filter(e=>!this._graphics.graphics.includes(e));return this._graphics.graphics.addMany(i),!0},this.clearGraphics=()=>{this._graphics.graphics.removeAll()},this.clearImage=()=>{this.imageSize=null,this.media=null,this._removeImageSphere()},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 i=e.filter(e=>this._graphics.graphics.includes(e));return this._graphics.removeMany(i),!0},this.restoreNavigationHandles=()=>{this._addNavigationHandles(!1)}}destroy(){this._cancelLoadWithController(),this.clearImage(),this._imageRenderer.destroy()}initialize(){this.state="initialized",this.addHandles([u(()=>null!=this.media&&this.autoLoad,this._loadWithController,g),p(()=>this.fov,()=>{this._reloadCamera()},g),p(()=>this.yaw,e=>{this.camera&&(this.camera.heading=e,this._reloadCamera())},g),p(()=>this.pitch,e=>{this.camera&&(this.camera.tilt=e,this._reloadCamera())},g),u(()=>this.imageRenderer.ready,()=>{this._addNavigationHandles(),this._addZoomHandles()},g),p(()=>this.clickAction,e=>{this.removeHandles(F.clickAction),"none"!==e&&this.addHandles(this.imageRenderer.on("click",this._handleImageClick))},g),p(()=>this.camera,(e,i)=>{this._panTask?.abort(),e?i?.tilt===e.tilt&&i.heading===e.heading||this._createPanTask():this._panTask=null}),this.currentGraphics.on("change",()=>{const e=Array.isArray(this._imageGraphic)?this._imageGraphic:[this._imageGraphic].filter(R),i=this.currentGraphics.map(e=>e.geometry.extent);e.forEach(e=>{e.visible=!0!==i.some(i=>i.intersects(e.geometry.extent))})})],F.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 distanceFactor(){return this.fov?1-5/this.fov:null}get fov(){return this.camera?.fov}set fov(e){Number.isFinite(e)&&this.zoomViewModel?.zoomTo(e)}get hfov(){if(!this.camera||!this.imageRenderer?.ready)return 0;const{fov:e}=this.camera,{size:[i,t]}=this.imageRenderer,a=i/t;return 2*m(Math.atan(Math.tan(d(e/2))*a/Math.sqrt(1+a**2)))}get imageRenderer(){return this._imageRenderer}get maxHFOV(){const{size:[e,i]}=this.imageRenderer;return this.imageRenderer.ready?A(k,e/i):k}get minHFOV(){const{size:[e,i]}=this.imageRenderer;return this.imageRenderer.ready?A(G,e/i):G}get updating(){return this.updatingHandles.updating}get vfov(){if(!this.camera||!this.imageRenderer?.ready)return 0;const{fov:e}=this.camera,{size:[i,t]}=this.imageRenderer,a=i/t;return 2*m(Math.atan(Math.tan(d(e/2))*(1/Math.sqrt(1+a**2))))}_clearImageSphere(){if(this.imagePyramid=null,this.imagePyramidLevel=-1,this.tileCache.clear(),!this._imageGraphic)return;const e=Array.isArray(this._imageGraphic)?this._imageGraphic:[this._imageGraphic];this._graphics.removeMany(e),this._imageGraphic=null,e.forEach(e=>e.destroy()),this._graphics.removeMany(this.currentGraphics.toArray())}async _loadMediaInternal(e,i){if(this.state="image-loading",this._removeImageSphere(),!e)throw this.state="ready",new o("panoramic-viewer:missing-media","No media provided to load.");try{const{meshOrMeshes:t,size:a,tileKeys:r}=await e.load(i),s=e.imagePyramid;if(c(i),s){this.imagePyramid=s,this.imagePyramidLevel=s.maximumPyramidLevel;const i=t;if(!i?.length)throw this.state="image-load-error",new o("panoramic-viewer:missing-tiles","No tiles were found in the pyramid",e.url);const a=i.map(x);a.forEach((e,i)=>{const t=r?.[i];e.attributes={key:t},this.tileCache.add(t)}),this._imageGraphic=a,this._graphics.addMany(this._imageGraphic)}else{const e=t;this._imageGraphic=x(e),this._graphics.add(this._imageGraphic)}return this.state="image-loaded",y(()=>this.imageRenderer.ready,i).then(()=>{const{size:[e,i]}=this.imageRenderer;this.fov=A(O,e/i)}),this.imageSize=a,this.media=e,t}catch(t){throw this._clearImageSphere(),this.state="image-load-error",t}}_reloadCamera(){this.camera=this.camera?.clone()}_removeImageSphere(){this._clearImageSphere(),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 i=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,i)),this._startPosition=this._targetPosition}async loadMedia(e,i){this.state="image-loading";const t=this.autoLoad;this.autoLoad=!1;return await this._loadMediaInternal(e,i).finally(()=>{this.autoLoad=t})}};e([_()],L.prototype,"_graphics",void 0),e([_()],L.prototype,"_imageGraphic",void 0),e([_({constructOnly:!0})],L.prototype,"currentGraphics",void 0),e([_()],L.prototype,"imagePyramid",void 0),e([_()],L.prototype,"imagePyramidLevel",void 0),e([_()],L.prototype,"_map",void 0),e([_()],L.prototype,"_imageRenderer",void 0),e([_()],L.prototype,"_loadController",void 0),e([_()],L.prototype,"zoomViewModel",void 0),e([_({type:Boolean})],L.prototype,"autoLoad",void 0),e([_({type:i})],L.prototype,"camera",null),e([S(new h({emit:"emit",hittest:"hittest",none:"none","pixel-location":"pixel-location"}))],L.prototype,"clickAction",void 0),e([_()],L.prototype,"distanceFactor",null),e([_({type:Number})],L.prototype,"fov",null),e([_({readOnly:!0})],L.prototype,"hfov",null),e([_({type:I})],L.prototype,"media",void 0),e([_()],L.prototype,"imageMeshDistance",void 0),e([_({readOnly:!0})],L.prototype,"imageRenderer",null),e([_()],L.prototype,"imageSize",void 0),e([_({readOnly:!0})],L.prototype,"maxHFOV",null),e([_({readOnly:!0})],L.prototype,"minHFOV",null),e([_({type:Number})],L.prototype,"pitch",void 0),e([_()],L.prototype,"state",void 0),e([_()],L.prototype,"updatingHandles",void 0),e([_()],L.prototype,"updating",null),e([_({readOnly:!0})],L.prototype,"vfov",null),e([_({type:Number})],L.prototype,"yaw",void 0),L=e([v("esri.widgets.PanoramicViewer.PanoramicViewerViewModel")],L);const T=L;export{T as default};