atriusmaps-node-sdk
Version:
This project provides an API to Atrius Personal Wayfinder maps within a Node environment. See the README.md for more information
2 lines (1 loc) • 4.25 kB
JavaScript
import{pick as t,isNil as o,map as n,omit as e,path as r}from"ramda";import{encode as i,calculateAdjacent as s}from"../../../src/extModules/geohasher.js";import{distance as l}from"../../../src/utils/geodesy.js";import d from"./minPriorityQueue.js";function u(r,s,l,d){const u={},c={},a=new Set;let h={};r.nodes.forEach((o=>{const n=s(o.floorId),e=l(o.floorId);!function(t){const o=t.floorId+":"+i(t.lat,t.lng).substr(0,7),n=t.floorId+":"+i(t.lat,t.lng).substr(0,8);c[o]||(c[o]=[]);c[o].push(t),c[n]||(c[n]=[]);c[n].push(t),u[t.id]=t}({...t(["id","lat","lng","floorId"],o),edges:[],ordinal:n,structureId:e})})),r.edges.forEach((t=>u[t.s].edges.push(function(t,n){const e=function(t){return t.x?"Security Checkpoint":""===t.t?"Ground":t.t}(t),r="escalator"!==e.toLowerCase()&&"stairs"!==e.toLowerCase(),i=f(t.s,t.d,n),s=t.l||i/60,l=t=>t.map((t=>({start:{lat:t.s[0],lng:t.s[1]},out:{lat:t.o[0],lng:t.o[1]},in:{lat:t.i[0],lng:t.i[1]},end:{lat:t.e[0],lng:t.e[1]}}))),d=t.p?l(t.p):null;return{distance:i,dst:t.d,o:t.o,isAccessible:r,isDriveway:!o(t.h)&&!t.h,src:t.s,transitTime:s,type:e,path:d,weight:s}}(t,u))));const p=t=>{if(void 0===t.floorId&&void 0===t.ordinal)throw Error("Endpoint specified in findRoute without floorId nor an ordinal");const o=t.lat||t.latitude,n=t.lng||t.longitude;return t.floorId?w(t.floorId,o,n,c,u):T(t.ordinal,o,n,u)};return{_nodes:u,_geoDb:c,_nodesToAvoid:a,addNodesToAvoid:t=>function(t){a.clear(),t.forEach((t=>a.add(t)))}(t),findClosestNode:(t,o,n)=>w(t,o,n,c,u),findShortestPath:(t,o,n)=>function(t,o,n,e={}){return I(p(t),p(o),n,a,h,d,e)}(t,o,u,n),findAllShortestPaths:function(t,o,n){const e=p(t),r=o.map((t=>p(t)));return e&&r.length?function(t,o,n,e,r={},i={},s={}){return o.map((o=>{try{return I(t,o,n,e,r,i,s)}catch(t){return null}}))}(e,r,u,a,h,d,n):[]},floorIdToOrdinal:s,floorIdToStructureId:l,updateWithSecurityWaitTime:function(t){h=n(e(["lastUpdated"]),t),y()},clearCache:y}}function f(t,o,n){const e=n[t],r=n[o];return l(e.lat,e.lng,r.lat,r.lng)}let c,a,h,p,g,m;const y=()=>{c={},a={},h={},p=new d,g=null,m={}};function I(t,o,n,e,i={},s={},l={}){for(t.id===g&&m===JSON.stringify(l)||(y(),p.offerWithPriority(t.id,0),c[t.id]=0,h[t.id]=!0,g=t.id,m=JSON.stringify(l));!p.isEmpty()&&!h[o.id];){const t=n[p.poll()],o=c[t.id];for(let n=0;n<t.edges.length;n++){const d=t.edges[n];if(e.size>0&&e.has(d.dst))continue;if(h[d.dst])continue;if(l.requiresAccessibility&&!d.isAccessible)continue;let u=d.weight;if(d.o&&i[d.o]){const t=i[d.o];t.queueTime&&(u=t.queueTime),t.isTemporarilyClosed&&(u=9999),d.securityWaitTimes=t}if(d.o&&s[d.o]){d.securityLane=s[d.o];const{type:t,id:o}=s[d.o],n=r(["selectedSecurityLanes",t],l);if(n&&!n.includes(o))continue}void 0===c[d.dst]?(a[d.dst]=t,c[d.dst]=o+u,p.offerWithPriority(d.dst,o+u)):c[d.dst]>o+u&&(c[d.dst]=o+u,a[d.dst]=t,p.raisePriority(d.dst,o+u))}h[t.id]=!0}if(!h[o.id])return null;const d=[];let u=o;for(;u;)d.push(u),u=a[u.id];return d.reverse()}function b(t,o,n,e){const r=o.substr(0,e),i=[];i.push(t+":"+s(s(r,"top"),"left")),i.push(t+":"+s(r,"top")),i.push(t+":"+s(s(r,"top"),"right")),i.push(t+":"+s(r,"left")),i.push(t+":"+r),i.push(t+":"+s(r,"right")),i.push(t+":"+s(s(r,"bottom"),"left")),i.push(t+":"+s(r,"bottom")),i.push(t+":"+s(s(r,"bottom"),"right"));const l=[];for(let t=0;t<i.length;t++){const o=n[i[t]];if(o)for(let t=0;t<o.length;t++)l.push(o[t])}return l}function w(t,o,n,e,r){const s=function(t,o,n){let e=b(t,o,n,8);return e.length>0?e:(e=b(t,o,n,7),e.length>0?e:null)}(t,i(o,n),e)||function(t,o,n,e){const r=Object.values(e).filter((o=>o.floorId===t)).map((t=>[t,l(t.lat,t.lng,o,n)]));if(!r.length)throw Error(`findClosestNodeByFloor2 found no nodes on floor ${t}`);return v(r)}(t,o,n,r),d=[];for(let t=0;t<s.length;t++){const e=l(o,n,s[t].lat,s[t].lng);d.push([s[t],e])}d.sort((function(t,o){return t[1]-o[1]}));const u=[];for(let t=0;t<d.length;t++)u.push(d[t][0]);return u[0]}function T(t,o,n,e){const r=Object.values(e).filter((o=>o.ordinal===t)).map((t=>[t,l(t.lat,t.lng,o,n)]));if(!r.length)throw Error(`findClosestNodeByOrdinal found no nodes on ordinal ${t}`);return v(r)}function v(t){let o=t[0];for(let n=1;n<t.length;n++)t[n][1]<o[1]&&(o=t[n]);return o[0]}export{u as createNavGraph,T as findClosestNodeByOrdinal,I as findShortestPath};