@expofp/floorplan
Version:
Interactive floor plan library for expos and events
2 lines (1 loc) • 11.1 kB
JavaScript
import{__decorate as n}from"tslib";import{Box as x,boxContainsPoint as G,pointDistance as L}from"@expofp/geometry";import{action as f,computed as g,observable as u}from"mobx";import{getName as B}from"../components/Kiosk/SetKiosk";import{mapCamera as T}from"../components/Map/camera";import{DEFAULT_UNITS as E,ORIENTATION_GRANTED_KEY as U}from"../constants";import P from"../data";import{fpGeo as w}from"../data/fpGeo";import{getLayerSvg as $,svgArea as h}from"../data/svg";import{GaEventActions as V,sendEventToGa as K}from"../tools/gtag";import D from"../tools/logger";import{areLayersEnabled as W}from"../utils/areLayersEnabled";import{calcSpeed as A}from"../utils/calcSpeed";import{calcTravelTime as I}from"../utils/calcTravelTime";import{calculateRelativeBearing as Z,convertGpsToLocal as C,isValidPointCoords as b}from"../utils/gps";import{boothToEndpoint as M,buildRoute as q,CURRENT_LOCATION_NAME as j,CURRENT_POSITION_POINT_ID as X,isWayfindingReady as Y,KIOSK_ANCHOR_POINT_ID as H,toArbitraryPoint as N}from"../wayfinding";import c,{layersStore as R,uiState as p}from".";import{BoothBase as y}from"./BoothStore";import{LayersMode as J}from"./LayerStore";import{revealLayer as O}from"./reveal-layer.js";function d(o){return typeof o=="string"?Number(o.replace(",",".")):o}export default class i{constructor(t){this.routeLines=[],this.routeDistance=null,this.currentPosition=null,this.requestCompass=!1,this.iconType=0,this.tempToBooth=null,this.focusEnabled=!0,this.prevZ=null,this.markersData={icons:[],markers:[]},this.prevMarkers=[],this.pendingReveal=null,this.showAccessible=!1,this.onlyAccessible=!1,this.currentRouteLayer=null,this.currentRouteExhibitor=null,this.routeUnits=E,this.isGpsTrackingEnabled=!0,this.rootStore=t,this.focusEnabled=!window.location.search}get canFindLocation(){return!!p.kioskData||!!this.currentPosition}selectRoute(t,e=!0,r=!1){if(e&&(p.list={type:"search",text:"",focused:!1}),t&&!t.from&&t.to){const s=this.resolveFallbackFrom();s&&(t=new Route(s,t.to,t.waypoints))}t?.from&&t?.to&&t.from===t.to&&(t=null);const l=[];t?.from&&t?.to&&window.setTimeout(()=>{this.rootStore.showMap()},navigator.userAgent.toLowerCase().indexOf("android")>-1?400:50),t?.from instanceof y&&t.from.visible&&l.push(t.from),t?.to instanceof y&&t.to.visible&&(this.tempToBooth=null,l.push(t.to)),!t&&c.fp.onDirection&&c.fp.onDirection(null);const a=f(()=>{if(this.rootStore.moveToList(l),p.details=t,t&&(!t.from||!t.to)&&p.overlayBottom&&(p.desiredOverlaySize="medium"),t?.to&&t?.from){const s=Q(t.from);s&&this.rootStore.layerStore.updateVisibility(s,!0)}if(!this.currentRouteLayer){const s=_(this.rootStore.layerStore,t?.from),m=_(this.rootStore.layerStore,t?.to);s?this.currentRouteLayer=s:m&&(this.currentRouteLayer=m)}e&&t?.from&&t?.to&&K(V.ClickDirections,`${t?.from?"From "+t.from.name:""} ${t?.to?"To "+t.to.name:""}`)});r?a():setTimeout(a,200)}rebuildRouteFromPosition(t){const e=p.selectedRoute;e?.to&&this.selectRoute(new Route(t,e.to,e.waypoints),!1,!0)}resolveFallbackFrom(){if(this.currentPosition)return N(this.currentPosition,j,X);const t=p.kioskData;return t?N({x:t.x,y:t.y,z:t.z??void 0},B(),H):null}setStartPoint(t){const e=p.selectedRoute;if(e?.to&&!e?.from&&t){const r=new Route(t,e.to,e.waypoints);this.selectRoute(r)}}get pathLayers(){return c.routeStore.routeLines?.map(t=>t.p0.layer)?.filter((t,e,r)=>r.indexOf(t)===e).map((t,e)=>({id:e+1,layer:c.layerStore.findLayer(t)}))}getNearestBooth(t){if(!t)return null;const e=this.rootStore.layerStore.findLayer(t.z),r=w?.properties.config,l=!!(t.lat&&t.lng),a=r&&l?C(t,r):t;return!a||!b(a.x)||!b(a.y)?null:this.rootStore.boothStore.booths.filter(s=>R.mode===J.Default||!e?s.visible&&s.rect:s.rect&&(typeof t.z!="number"&&!t.z&&s.visible||e.name===s.layer?.name)).sort((s,m)=>L(a,s.rect.center)-L(a,m.rect.center))[0]||null}setMarkers(t){this.markersData.markers=(t?.markers??[]).map(tt),this.markersData.icons=t?.icons??[]}selectMarker(t,e){const r=this.markersData.markers.find(a=>a.id===t);this.markersData.markers.forEach(a=>a.active=!1),r&&(r.active=!0);const l=c.layerStore.findLayer(r?.z);if(e&&r){l&&!l?.visible&&R.updateVisibility(l,!0);const a=T();return a?a.api.panTo({x:r.x,y:r.y}):(D.warn("Map camera is not mounted. Cannot pan to marker."),Promise.resolve())}return Promise.resolve()}get selectedMarkers(){return this.markersData.markers.filter(t=>t.active)}get layers(){const t=[];return c.routeStore.routeLines?.map(e=>e.p0.layer).forEach(e=>{t.indexOf(e)===-1&&t.push(e)}),t.map(e=>c.layerStore.layers.find(r=>r.name===e)).filter(e=>!!e)}clickRoute(t,e){window.__resett&&window.__resett(),this.rootStore.uiState.menu=!1,p.list.type==="route-planner"&&(p.list={type:"search",text:"",focused:!1}),this.selectRoute(new Route(t,e))}selectCurrentPosition(t,e=!0,r){clearTimeout(this.cpTimeout),t&&(t.x=d(t.x),t.y=d(t.y),t.lat!==void 0&&(t.lat=d(t.lat)),t.lng!==void 0&&(t.lng=d(t.lng)),W()||(t.z=void 0));const l=e&&this.rootStore.uiState.details&&!(this.rootStore.uiState.details instanceof Route),a=e&&!l&&(this.focusEnabled||this.prevZ!=t?.z);this.focusEnabled&&(this.focusEnabled=!1),this.prevZ=t?.z?.toString()??null,this.iconType=r?1:0;const s=t?et(t):null;if(!t||!s){this.currentPosition=null;return}const m=c.layerStore.findLayer(t.z),k=new CurrentPosition(s.x,s.y,m?.name||this.currentRouteLayer?.name,Z(s),t.lat,t.lng);let v=!this.routeLines?.length;m&&this.routeLines?.length&&(v=!!this.routeLines.find(S=>S.p0.layer===m.name||S.p1.layer===m.name));const F=a&&v;this.currentPosition=k,F&&this.focusOnPosition(k,m),this.gpsEnabled||(this.cpTimeout=setTimeout(()=>{this.currentPosition&&this.selectCurrentPosition(null,!1)},30*1e3))}findLocation(){if(!this.canFindLocation)return;const t=this.currentPosition??p.kioskData;t&&(this.currentPosition&&localStorage.getItem(U)==="false"&&(c.routeStore.requestCompass=!0),this.pendingReveal?.(),this.pendingReveal=O({layer:c.layerStore.findLayer(t.z),show:e=>R.updateVisibility(e,!0),then:()=>{p.moveToRect=this.findLocationRect(t)}}))}findLocationRect(t){const e=x.fromCenter(t,{x:100,y:100});if(e.intersects(h))return e;const r=Math.max(h.min.x,Math.min(t.x,h.max.x)),l=Math.max(h.min.y,Math.min(t.y,h.max.y)),a=Math.min(h.size.width,h.size.height)*.3,s=x.fromCenter({x:r,y:l},{x:a,y:a}).intersection(h);return s?x.fromUnion(e,s):e}focusOnPosition(t,e){this.pendingReveal?.(),this.pendingReveal=O({layer:e,show:r=>R.updateVisibility(r,!0),then:()=>{if(c.maplibreStore.showMaplibre){p.moveToLocation=!0;return}const r=T();if(r){r.api.panTo({x:t.x,y:t.y});return}D.warn("Map camera is not mounted. Cannot pan to current position.")}})}get routeInfo(){const t=this.routeDistance,e=this.routeUnits;return t?{distance:`${t}${e}`,units:e,time:I(t,A(e))}:null}updateRoute(t,e){!t?.length&&!this.routeLines.length||(this.routeLines=t,this.updateRoutePoints())}updateRouteDistance(t){if(t==null)return;const e=$(),r=(e.getAttribute("units")||E).toLowerCase?.().trim(),l=e.getAttribute("fp-ver")?.startsWith("5")??!1;this.routeDistance=Math.round(t/(l?1:10)),this.routeUnits=r,this.updateRoutePoints()}updateRoutePoints(){const t=p.selectedRoute,e=this.routeDistance,r=this.routeUnits;c.fp.onDirection&&setTimeout(()=>{c.fp.onDirection({from:z(t?.from??null),to:z(t?.to??null),lines:this.routeLines,distance:e==null?"":`${e}${r}`,units:r,time:I(e??0,A(r))})},200)}checkRoutes(){if(!Y()){console.warn("checkRoutes: wayfinding is not initialized \u2014 call createWayfinding() first. Skipping route check.");return}const t=c.boothStore.booths;console.info(`Route check started ${t.length}.... `);for(let e=0;e<t.length;e++){const r=t[e];for(let l=e+1;l<t.length;l++){const a=t[l];q(M(r),M(a)).lines.length||console.warn(`No route found from ${r.name} to ${a.name}`)}}console.info("Route check done....")}setGpsTrackingEnabled(t){this.isGpsTrackingEnabled=t}get gpsEnabled(){return P.autoTrackingGps&&this.isGpsTrackingEnabled&&!P.enableIPS}setOnlyAccessible(t){this.onlyAccessible=t}}n([u],i.prototype,"routeLines",void 0),n([u],i.prototype,"routeDistance",void 0),n([u],i.prototype,"currentPosition",void 0),n([u],i.prototype,"requestCompass",void 0),n([u],i.prototype,"iconType",void 0),n([u],i.prototype,"tempToBooth",void 0),n([u],i.prototype,"focusEnabled",void 0),n([u],i.prototype,"prevZ",void 0),n([u],i.prototype,"markersData",void 0),n([u],i.prototype,"prevMarkers",void 0),n([u],i.prototype,"showAccessible",void 0),n([u],i.prototype,"onlyAccessible",void 0),n([u],i.prototype,"currentRouteLayer",void 0),n([u],i.prototype,"currentRouteExhibitor",void 0),n([g],i.prototype,"canFindLocation",null),n([f],i.prototype,"selectRoute",null),n([f],i.prototype,"rebuildRouteFromPosition",null),n([f],i.prototype,"setStartPoint",null),n([g({keepAlive:!0})],i.prototype,"pathLayers",null),n([f],i.prototype,"setMarkers",null),n([f],i.prototype,"selectMarker",null),n([g({keepAlive:!0})],i.prototype,"selectedMarkers",null),n([g({keepAlive:!0})],i.prototype,"layers",null),n([f],i.prototype,"clickRoute",null),n([f],i.prototype,"selectCurrentPosition",null),n([f],i.prototype,"findLocation",null),n([u],i.prototype,"routeUnits",void 0),n([g],i.prototype,"routeInfo",null),n([f],i.prototype,"updateRoute",null),n([f],i.prototype,"updateRouteDistance",null),n([f],i.prototype,"updateRoutePoints",null),n([f],i.prototype,"checkRoutes",null),n([u],i.prototype,"isGpsTrackingEnabled",void 0),n([f],i.prototype,"setGpsTrackingEnabled",null),n([g({keepAlive:!0})],i.prototype,"gpsEnabled",null),n([f],i.prototype,"setOnlyAccessible",null);function Q(o){if(o)return o instanceof y?o.layer?.name:o.layer}function _(o,t){return t?t instanceof y?t.layer??null:o.findLayer(t.layer):null}function tt(o){return{...o,x:d(o.x),y:d(o.y),lat:o.lat===void 0?void 0:d(o.lat),lng:o.lng===void 0?void 0:d(o.lng)}}function et(o){const t=w?.properties.config??null;let e=null;return t&&G({min:t.p0,max:t.p2},o)?e={...o}:t&&b(o.lat)&&b(o.lng)?e=C(o,t):t||(e=o),e||null}export function findBooth(o){return c.boothStore.findBooth(o)||c.exhibitorStore.findExhibitor(o)?.booths[0]}export function findEntityByExternalId(o){const t=c.boothStore.boothByExternalId.get(o);if(t)return{type:"booth",entity:t};const e=c.exhibitorStore.exhibitorByExternalId.get(o);if(e)return{type:"exhibitor",entity:e}}export function separateExternalIds(o){const t=[],e=[];for(const r of o){const l=findEntityByExternalId(r);l&&(l.type==="booth"?t.push(r):e.push(r))}return{boothExternalIds:t,exhibitorExternalIds:e}}export function extractRoute(o,t,e){return new Route(findBooth(o)??null,findBooth(t)??null,e?.map(r=>findBooth(r)).filter(r=>!!r))}export class Route{constructor(t,e,r){this.from=t,this.to=e,this.waypoints=r;const l=t instanceof y?t.id:void 0,a=e instanceof y?e.id:void 0;this.waypoints=r?.filter(s=>s&&s.id!==l&&s.id!==a)}}function z(o){return o?o instanceof y?{id:o.id,name:o.name,externalId:o.externalId,layer:{name:o.layer?.name,description:o.layer?.description}}:{id:Number.MAX_SAFE_INTEGER,name:o.name,externalId:void 0,layer:{name:o.layer,description:void 0}}:null}export class CurrentPosition{constructor(t,e,r,l,a,s){this.x=t,this.y=e,this.z=r,this.angle=l,this.lat=a,this.lng=s}}