atriusmaps-node-sdk 3.3.981 → 3.3.982

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var version = "3.3.981";
5
+ var version = "3.3.982";
6
6
  var pkg = {
7
7
  version: version};
8
8
 
@@ -58,11 +58,11 @@ function create(app, config) {
58
58
  });
59
59
  const isNotPortal = (poi) => poi.category.indexOf("portal") === -1 && poi.category !== "element.door";
60
60
  const noPortalPois = Object.values(R__namespace.pickBy(isNotPortal, poisSameFloor));
61
- const poisWithDistance = await app.bus.get("wayfinder/addPathTimeMultiple", {
61
+ const poisWithTime = await app.bus.get("wayfinder/addPathTimeMultiple", {
62
62
  pois: noPortalPois,
63
63
  startLocation
64
64
  });
65
- return R__namespace.sortBy(R__namespace.prop("distance"), Object.values(poisWithDistance)).slice(0, 50);
65
+ return Object.values(poisWithTime).slice(0, 50);
66
66
  }
67
67
  app.bus.on("search/queryCategory", async ({ category, categoryName, searchTerm }) => {
68
68
  const pois = await state.indexesCreated.then(() => state.poiSearch.search({ query: searchTerm || category }));
@@ -6,12 +6,14 @@ var geohasher = require('../../../src/extModules/geohasher.js');
6
6
  var minPriorityQueue = require('./minPriorityQueue.js');
7
7
 
8
8
  const DEFAULT_WALKING_SPEED_M_PER_MIN = 60;
9
- const CLOSED_CHECKPOINT_EDGE_WEIGHT = 9999;
9
+ const CLOSED_CHECKPOINT_WAIT_MINUTES = 9999;
10
+ function getEdgeTraversalTime(edge) {
11
+ return edge.securityWaitTimes ? edge.waitTime : edge.transitTime;
12
+ }
10
13
  function createNavGraph(data, floorIdToOrdinal, floorIdToStructureId, securityLanesMap) {
11
14
  const nodes = {};
12
15
  const geoDb = {};
13
16
  const nodesToAvoid = /* @__PURE__ */ new Set();
14
- let securityWaitTimes = {};
15
17
  data.nodes.forEach((nodeData) => {
16
18
  const ordinal = floorIdToOrdinal(nodeData.floorId);
17
19
  const structureId = floorIdToStructureId(nodeData.floorId);
@@ -62,7 +64,8 @@ function createNavGraph(data, floorIdToOrdinal, floorIdToStructureId, securityLa
62
64
  transitTime,
63
65
  type,
64
66
  path,
65
- weight: transitTime
67
+ waitTime: 0
68
+ // populated by updateWithSecurityWaitTime
66
69
  };
67
70
  }
68
71
  function getEdgeType(data2) {
@@ -85,7 +88,7 @@ function createNavGraph(data, floorIdToOrdinal, floorIdToStructureId, securityLa
85
88
  function findShortestPathEntry(start, end, nodes2, options = {}) {
86
89
  const startNode = findClosestNode(start);
87
90
  const endNode = findClosestNode(end);
88
- return findShortestPath(startNode, endNode, nodes2, nodesToAvoid, securityWaitTimes, securityLanesMap, options);
91
+ return findShortestPath(startNode, endNode, nodes2, nodesToAvoid, securityLanesMap, options);
89
92
  }
90
93
  function updateNodesToAvoid(nodes2) {
91
94
  nodesToAvoid.clear();
@@ -97,20 +100,29 @@ function createNavGraph(data, floorIdToOrdinal, floorIdToStructureId, securityLa
97
100
  if (!startNode || !destNodeArray.length) {
98
101
  return [];
99
102
  }
100
- return findAllShortestPathsImpl(
101
- startNode,
102
- destNodeArray,
103
- nodes,
104
- nodesToAvoid,
105
- securityWaitTimes,
106
- securityLanesMap,
107
- options
108
- );
103
+ return findAllShortestPathsImpl(startNode, destNodeArray, nodes, nodesToAvoid, securityLanesMap, options);
109
104
  }
110
105
  function updateWithSecurityWaitTime(waitTimesData) {
111
- securityWaitTimes = R.map(R.omit(["lastUpdated"]), waitTimesData);
106
+ const waitTimes = R.map(R.omit(["lastUpdated"]), waitTimesData);
107
+ forEachEdge((edge) => {
108
+ const dynamicData = edge.o === void 0 ? void 0 : waitTimes[edge.o];
109
+ if (!dynamicData) {
110
+ edge.waitTime = 0;
111
+ delete edge.securityWaitTimes;
112
+ return;
113
+ }
114
+ edge.securityWaitTimes = dynamicData;
115
+ edge.waitTime = dynamicData.isTemporarilyClosed ? CLOSED_CHECKPOINT_WAIT_MINUTES : dynamicData.queueTime ?? 0;
116
+ });
112
117
  clearCache();
113
118
  }
119
+ function forEachEdge(fn) {
120
+ for (const node of Object.values(nodes)) {
121
+ for (const edge of node.edges) {
122
+ fn(edge);
123
+ }
124
+ }
125
+ }
114
126
  return {
115
127
  _nodes: nodes,
116
128
  _geoDb: geoDb,
@@ -133,10 +145,10 @@ function distanceBetweenNodes(n1, n2, nodes) {
133
145
  const distance = geodesy.distance(node1.lat, node1.lng, node2.lat, node2.lng);
134
146
  return distance;
135
147
  }
136
- function findAllShortestPathsImpl(start, destinations, nodes, nodesToAvoid, securityWaitTimes = {}, securityLanesMap = {}, options = {}) {
148
+ function findAllShortestPathsImpl(start, destinations, nodes, nodesToAvoid, securityLanesMap = {}, options = {}) {
137
149
  return destinations.map((d) => {
138
150
  try {
139
- return findShortestPath(start, d, nodes, nodesToAvoid, securityWaitTimes, securityLanesMap, options);
151
+ return findShortestPath(start, d, nodes, nodesToAvoid, securityLanesMap, options);
140
152
  } catch {
141
153
  return null;
142
154
  }
@@ -156,7 +168,7 @@ const clearCache = () => {
156
168
  lastStartId = null;
157
169
  lastOptionsStr = {};
158
170
  };
159
- function findShortestPath(start, end, nodes, nodesToAvoid, securityWaitTimes = {}, securityLanesMap = {}, options = {}) {
171
+ function findShortestPath(start, end, nodes, nodesToAvoid, securityLanesMap = {}, options = {}) {
160
172
  if (start.id !== lastStartId || lastOptionsStr !== JSON.stringify(options)) {
161
173
  clearCache();
162
174
  visitQueue.offerWithPriority(start.id, 0);
@@ -183,17 +195,7 @@ function findShortestPath(start, end, nodes, nodesToAvoid, securityWaitTimes = {
183
195
  if (options.requiresAccessibility && !e.isAccessible) {
184
196
  continue;
185
197
  }
186
- let weight = e.weight;
187
- if (e.o && securityWaitTimes[e.o]) {
188
- const dynamicData = securityWaitTimes[e.o];
189
- if (dynamicData.queueTime) {
190
- weight = dynamicData.queueTime;
191
- }
192
- if (dynamicData.isTemporarilyClosed) {
193
- weight = CLOSED_CHECKPOINT_EDGE_WEIGHT;
194
- }
195
- e.securityWaitTimes = dynamicData;
196
- }
198
+ const weight = getEdgeTraversalTime(e);
197
199
  const securityLanesById = securityLanesMap;
198
200
  if (e.o && securityLanesById[e.o]) {
199
201
  e.securityLane = securityLanesById[e.o];
@@ -308,3 +310,4 @@ function selectShortest(ar) {
308
310
  exports.createNavGraph = createNavGraph;
309
311
  exports.findClosestNodeByOrdinal = findClosestNodeByOrdinal;
310
312
  exports.findShortestPath = findShortestPath;
313
+ exports.getEdgeTraversalTime = getEdgeTraversalTime;
@@ -243,7 +243,7 @@ function create(app, config) {
243
243
  if (path && path.length) {
244
244
  return {
245
245
  ...updatedPoi,
246
- transitTime: calculateTotalPathProperty(path, "transitTime"),
246
+ transitTime: calculateTotalPathTime(path),
247
247
  distance: calculateTotalPathProperty(path, "distance")
248
248
  };
249
249
  } else {
@@ -255,6 +255,9 @@ function create(app, config) {
255
255
  function calculateTotalPathProperty(path, propertyName) {
256
256
  return R__namespace.aperture(2, path).map(([from, to]) => getEdgeTo(to.id)(from)).map((edge) => edge?.[propertyName] ?? 0).reduce((totalTime, edgeTime) => totalTime + edgeTime, 0);
257
257
  }
258
+ function calculateTotalPathTime(path) {
259
+ return R__namespace.aperture(2, path).map(([from, to]) => getEdgeTo(to.id)(from)).reduce((total, edge) => total + (edge ? navGraph.getEdgeTraversalTime(edge) : 0), 0);
260
+ }
258
261
  function addEndpointInformation(poi, endpoint, endpointType) {
259
262
  return {
260
263
  ...poi,
@@ -360,7 +363,7 @@ function create(app, config) {
360
363
  return pathsSecondary;
361
364
  }
362
365
  function resolvePathTime(path, distance) {
363
- return path && path.length ? calculateTotalPathProperty(path, "transitTime") : getTransitTime(distance);
366
+ return path && path.length ? calculateTotalPathTime(path) : getTransitTime(distance);
364
367
  }
365
368
  function resolvePathDistance(path, startLocation, endLocation) {
366
369
  return path && path.length ? calculateTotalPathProperty(path, "distance") : getGeoDistance(endLocation, startLocation);
@@ -1 +1 @@
1
- var a="3.3.981",e={version:a};export{e as default,a as version};
1
+ var a="3.3.982",e={version:a};export{e as default,a as version};
@@ -1 +1 @@
1
- import*as e from"ramda";import a from"zousan";import{getLocalized as r}from"../../../src/utils/configUtils.js";import{randomizeArray as s,arrayPick as t}from"../../../src/utils/rand.js";import n from"./poiSearch.js";import o from"./searchTypeahead.js";function i(i,c){const u={poiSearch:null,typeahead:null,indexesCreated:new a,defaultSearchTerms:null,specialQueryTerms:{}},d=async()=>{const e=await i.bus.get("poi/getAll");u.poiSearch=n(e,i.i18n().language),u.typeahead=o(e,u.poiSearch.search,i.i18n().language),u.defaultSearchTerms=r(c,"defaultSearchTerms",i.i18n().language),u.indexesCreated.resolve()};async function h(){const a=await i.bus.getFirst("user/getPhysicalLocation");if(!a?.floorId)return[];const r=await i.bus.get("poi/getByFloorId",{floorId:a?.floorId}),s=Object.values(e.pickBy(e=>-1===e.category.indexOf("portal")&&"element.door"!==e.category,r)),t=await i.bus.get("wayfinder/addPathTimeMultiple",{pois:s,startLocation:a});return e.sortBy(e.prop("distance"),Object.values(t)).slice(0,50)}i.bus.on("search/queryNearby",async()=>{const e=await h();return i.bus.send("search/showNearby",{pois:e,term:"Nearby"}),e}),i.bus.on("search/queryNearbyAsync",h),i.bus.on("search/queryCategory",async({category:e,categoryName:a,searchTerm:r})=>{const s=await u.indexesCreated.then(()=>u.poiSearch.search({query:r||e}));return i.bus.send("search/showCategory",{pois:s,category:e,categoryName:a}),s}),i.bus.on("search/query",({term:e})=>u.indexesCreated.then(()=>{const a=u.poiSearch.search({query:e});return i.bus.send("search/showSearchResults",{results:a,term:e}),a})),i.bus.on("search/queryAsync",({term:e})=>u.indexesCreated.then(()=>u.poiSearch.search({query:e}))),i.bus.on("search/queryWithSpecial",({term:e})=>{if(u.specialQueryTerms[e]){const{event:a,params:r}=u.specialQueryTerms[e];return i.bus.send(a,r)}return i.bus.get("search/query",{term:e})}),i.bus.on("search/getDefaultSearchTerms",async({limit:e=5}={})=>{const a=u.defaultSearchTerms,r=a&&a.length?a:await async function(e){const a=(await i.bus.send("poi/getAllCategories"))[0],r=Array.from(new Set(a));return s(r).slice(0,e)}(e);return i.bus.send("search/showDefaultSearchKeywords",{keywords:r}),r}),i.bus.on("search/getDefaultSearchPois",async({limit:a=5}={})=>{const r=await i.bus.get("poi/getAll"),s=e.pickBy(e=>e.isNavigable,r);return t(Object.values(s),a)}),i.bus.on("search/registerSpecialQuery",({term:e,event:a,params:r,addKeyword:s=!0})=>{u.indexesCreated.then(()=>{s&&u.typeahead.addKeyword(e),u.specialQueryTerms[e]={event:a,params:r}})}),i.bus.on("search/addKeywords",({keywords:e})=>u.indexesCreated.then(()=>e.forEach(e=>u.typeahead.addKeyword(e)))),i.bus.on("search/typeahead",({term:e,limit:a})=>u.indexesCreated.then(()=>{const{keywords:r,pois:s}=u.typeahead.query(e,a);return{keywords:r,pois:s,term:e}})),i.bus.on("venueData/loadNewVenue",()=>{u.indexesCreated=new a,d()}),i.bus.on("poi/setDynamicData",async({plugin:e,idValuesMap:a})=>{if("grab"!==e)return;const r=Object.keys(a).map(e=>i.bus.get("poi/getById",{id:e}));return Promise.all(r).then(e=>u.indexesCreated.then(()=>u.poiSearch.updateMultiple(e)))}),i.bus.on("poi/updated",async({pois:e})=>{e&&0!==e.length&&(await u.indexesCreated,u.poiSearch.updateMultiple(e),u.typeahead.updatePOIs(e),i.bus.send("search/typeaheadChanged",{pois:e}))});return{init:d,runTest:async(e,a)=>(await a(),u)}}export{i as create};
1
+ import*as e from"ramda";import a from"zousan";import{getLocalized as r}from"../../../src/utils/configUtils.js";import{randomizeArray as s,arrayPick as t}from"../../../src/utils/rand.js";import n from"./poiSearch.js";import o from"./searchTypeahead.js";function i(i,c){const u={poiSearch:null,typeahead:null,indexesCreated:new a,defaultSearchTerms:null,specialQueryTerms:{}},d=async()=>{const e=await i.bus.get("poi/getAll");u.poiSearch=n(e,i.i18n().language),u.typeahead=o(e,u.poiSearch.search,i.i18n().language),u.defaultSearchTerms=r(c,"defaultSearchTerms",i.i18n().language),u.indexesCreated.resolve()};async function h(){const a=await i.bus.getFirst("user/getPhysicalLocation");if(!a?.floorId)return[];const r=await i.bus.get("poi/getByFloorId",{floorId:a?.floorId}),s=Object.values(e.pickBy(e=>-1===e.category.indexOf("portal")&&"element.door"!==e.category,r)),t=await i.bus.get("wayfinder/addPathTimeMultiple",{pois:s,startLocation:a});return Object.values(t).slice(0,50)}i.bus.on("search/queryNearby",async()=>{const e=await h();return i.bus.send("search/showNearby",{pois:e,term:"Nearby"}),e}),i.bus.on("search/queryNearbyAsync",h),i.bus.on("search/queryCategory",async({category:e,categoryName:a,searchTerm:r})=>{const s=await u.indexesCreated.then(()=>u.poiSearch.search({query:r||e}));return i.bus.send("search/showCategory",{pois:s,category:e,categoryName:a}),s}),i.bus.on("search/query",({term:e})=>u.indexesCreated.then(()=>{const a=u.poiSearch.search({query:e});return i.bus.send("search/showSearchResults",{results:a,term:e}),a})),i.bus.on("search/queryAsync",({term:e})=>u.indexesCreated.then(()=>u.poiSearch.search({query:e}))),i.bus.on("search/queryWithSpecial",({term:e})=>{if(u.specialQueryTerms[e]){const{event:a,params:r}=u.specialQueryTerms[e];return i.bus.send(a,r)}return i.bus.get("search/query",{term:e})}),i.bus.on("search/getDefaultSearchTerms",async({limit:e=5}={})=>{const a=u.defaultSearchTerms,r=a&&a.length?a:await async function(e){const a=(await i.bus.send("poi/getAllCategories"))[0],r=Array.from(new Set(a));return s(r).slice(0,e)}(e);return i.bus.send("search/showDefaultSearchKeywords",{keywords:r}),r}),i.bus.on("search/getDefaultSearchPois",async({limit:a=5}={})=>{const r=await i.bus.get("poi/getAll"),s=e.pickBy(e=>e.isNavigable,r);return t(Object.values(s),a)}),i.bus.on("search/registerSpecialQuery",({term:e,event:a,params:r,addKeyword:s=!0})=>{u.indexesCreated.then(()=>{s&&u.typeahead.addKeyword(e),u.specialQueryTerms[e]={event:a,params:r}})}),i.bus.on("search/addKeywords",({keywords:e})=>u.indexesCreated.then(()=>e.forEach(e=>u.typeahead.addKeyword(e)))),i.bus.on("search/typeahead",({term:e,limit:a})=>u.indexesCreated.then(()=>{const{keywords:r,pois:s}=u.typeahead.query(e,a);return{keywords:r,pois:s,term:e}})),i.bus.on("venueData/loadNewVenue",()=>{u.indexesCreated=new a,d()}),i.bus.on("poi/setDynamicData",async({plugin:e,idValuesMap:a})=>{if("grab"!==e)return;const r=Object.keys(a).map(e=>i.bus.get("poi/getById",{id:e}));return Promise.all(r).then(e=>u.indexesCreated.then(()=>u.poiSearch.updateMultiple(e)))}),i.bus.on("poi/updated",async({pois:e})=>{e&&0!==e.length&&(await u.indexesCreated,u.poiSearch.updateMultiple(e),u.typeahead.updatePOIs(e),i.bus.send("search/typeaheadChanged",{pois:e}))});return{init:d,runTest:async(e,a)=>(await a(),u)}}export{i as create};
@@ -1 +1 @@
1
- import{pick as t,isNil as o,map as n,omit as e,path as r}from"ramda";import{distance as i}from"../../../src/utils/geodesy.js";import{encode as s,calculateAdjacent as l}from"../../../src/extModules/geohasher.js";import u from"./minPriorityQueue.js";function d(r,i,l,u){const d={},f={},a=new Set;let h={};r.nodes.forEach(o=>{const n=i(o.floorId),e=l(o.floorId);!function(t){const o=t.floorId+":"+s(t.lat,t.lng).substr(0,7),n=t.floorId+":"+s(t.lat,t.lng).substr(0,8);f[o]||(f[o]=[]);f[o].push(t),f[n]||(f[n]=[]);f[n].push(t),d[t.id]=t}({...t(["id","lat","lng","floorId"],o),edges:[],ordinal:n,structureId:e})}),r.edges.forEach(t=>d[t.s].edges.push(function(t,n){const e=function(t){if(t.x)return"Security Checkpoint";if(""===t.t)return"Ground";return t.t}(t),r=e.toLowerCase(),i="escalator"!==r&&"stairs"!==r,s=c(t.s,t.d,n),l=t.l||s/60,u=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?u(t.p):null;return{distance:s,dst:t.d,o:t.o,isAccessible:i,isDriveway:!o(t.h)&&!t.h,src:t.s,transitTime:l,type:e,path:d,weight:l}}(t,d)));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,f,d):v(t.ordinal,o,n,d)};return{_nodes:d,_geoDb:f,_nodesToAvoid:a,addNodesToAvoid:t=>function(t){a.clear(),t.forEach(t=>a.add(t))}(t),findClosestNode:(t,o,n)=>w(t,o,n,f,d),findShortestPath:(t,o,n)=>function(t,o,n,e={}){return I(p(t),p(o),n,a,h,u,e)}(t,o,d,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{return null}})}(e,r,d,a,h,u,n):[]},floorIdToOrdinal:i,floorIdToStructureId:l,updateWithSecurityWaitTime:function(t){h=n(e(["lastUpdated"]),t),y()},clearCache:y}}function c(t,o,n){const e=n[t],r=n[o];return i(e.lat,e.lng,r.lat,r.lng)}let f,a,h,p,g,m;const y=()=>{f={},a={},h={},p=new u,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),f[t.id]=0,h[t.id]=!0,g=t.id,m=JSON.stringify(l));!p.isEmpty()&&!h[o.id];){const t=p.poll();if(null==t)break;const o=n[t],u=f[o.id];for(let t=0;t<o.edges.length;t++){const n=o.edges[t];if(e.size>0&&e.has(n.dst))continue;if(h[n.dst])continue;if(l.requiresAccessibility&&!n.isAccessible)continue;let d=n.weight;if(n.o&&i[n.o]){const t=i[n.o];t.queueTime&&(d=t.queueTime),t.isTemporarilyClosed&&(d=9999),n.securityWaitTimes=t}const c=s;if(n.o&&c[n.o]){n.securityLane=c[n.o];const{type:t,id:o}=c[n.o],e=r(["selectedSecurityLanes",t],l);if(e&&!e.includes(o))continue}void 0===f[n.dst]?(a[n.dst]=o,f[n.dst]=u+d,p.offerWithPriority(n.dst,u+d)):f[n.dst]>u+d&&(f[n.dst]=u+d,a[n.dst]=o,p.raisePriority(n.dst,u+d))}h[o.id]=!0}if(!h[o.id])return null;const u=[];let d=o;for(;d;)u.push(d),d=a[d.id];return u.reverse()}function b(t,o,n,e){const r=o.substr(0,e),i=[];i.push(t+":"+l(l(r,"top"),"left")),i.push(t+":"+l(r,"top")),i.push(t+":"+l(l(r,"top"),"right")),i.push(t+":"+l(r,"left")),i.push(t+":"+r),i.push(t+":"+l(r,"right")),i.push(t+":"+l(l(r,"bottom"),"left")),i.push(t+":"+l(r,"bottom")),i.push(t+":"+l(l(r,"bottom"),"right"));const s=[];for(let t=0;t<i.length;t++){const o=n[i[t]];if(o)for(let t=0;t<o.length;t++)s.push(o[t])}return s}function w(t,o,n,e,r){const l=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,s(o,n),e),u=l??[T(t,o,n,r)],d=[];for(let t=0;t<u.length;t++){const e=i(o,n,u[t].lat,u[t].lng);d.push([u[t],e])}d.sort(function(t,o){return t[1]-o[1]});const c=[];for(let t=0;t<d.length;t++){const o=d[t];o&&c.push(o[0])}return c[0]}function T(t,o,n,e){const r=Object.values(e).filter(o=>o.floorId===t).map(t=>[t,i(t.lat,t.lng,o,n)]);if(!r.length)throw Error(`findClosestNodeByFloor2 found no nodes on floor ${t}`);return S(r)}function v(t,o,n,e){const r=Object.values(e).filter(o=>o.ordinal===t).map(t=>[t,i(t.lat,t.lng,o,n)]);if(!r.length)throw Error(`findClosestNodeByOrdinal found no nodes on ordinal ${t}`);return S(r)}function S(t){let o=t[0];for(let n=1;n<t.length;n++){const e=t[n];e&&e[1]<o[1]&&(o=e)}return o[0]}export{d as createNavGraph,v as findClosestNodeByOrdinal,I as findShortestPath};
1
+ import{pick as t,isNil as o,map as n,omit as e,path as r}from"ramda";import{distance as i}from"../../../src/utils/geodesy.js";import{encode as s,calculateAdjacent as l}from"../../../src/extModules/geohasher.js";import u from"./minPriorityQueue.js";function d(t){return t.securityWaitTimes?t.waitTime:t.transitTime}function c(r,i,l,u){const d={},c={},a=new Set;r.nodes.forEach(o=>{const n=i(o.floorId),e=l(o.floorId);!function(t){const o=t.floorId+":"+s(t.lat,t.lng).substr(0,7),n=t.floorId+":"+s(t.lat,t.lng).substr(0,8);c[o]||(c[o]=[]);c[o].push(t),c[n]||(c[n]=[]);c[n].push(t),d[t.id]=t}({...t(["id","lat","lng","floorId"],o),edges:[],ordinal:n,structureId:e})}),r.edges.forEach(t=>d[t.s].edges.push(function(t,n){const e=function(t){if(t.x)return"Security Checkpoint";if(""===t.t)return"Ground";return t.t}(t),r=e.toLowerCase(),i="escalator"!==r&&"stairs"!==r,s=f(t.s,t.d,n),l=t.l||s/60,u=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?u(t.p):null;return{distance:s,dst:t.d,o:t.o,isAccessible:i,isDriveway:!o(t.h)&&!t.h,src:t.s,transitTime:l,type:e,path:d,waitTime:0}}(t,d)));const h=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?v(t.floorId,o,n,c,d):S(t.ordinal,o,n,d)};return{_nodes:d,_geoDb:c,_nodesToAvoid:a,addNodesToAvoid:t=>function(t){a.clear(),t.forEach(t=>a.add(t))}(t),findClosestNode:(t,o,n)=>v(t,o,n,c,d),findShortestPath:(t,o,n)=>function(t,o,n,e={}){return b(h(t),h(o),n,a,u,e)}(t,o,d,n),findAllShortestPaths:function(t,o,n){const e=h(t),r=o.map(t=>h(t));return e&&r.length?function(t,o,n,e,r={},i={}){return o.map(o=>{try{return b(t,o,n,e,r,i)}catch{return null}})}(e,r,d,a,u,n):[]},floorIdToOrdinal:i,floorIdToStructureId:l,updateWithSecurityWaitTime:function(t){const o=n(e(["lastUpdated"]),t);!function(t){for(const o of Object.values(d))for(const n of o.edges)t(n)}(t=>{const n=void 0===t.o?void 0:o[t.o];if(!n)return t.waitTime=0,void delete t.securityWaitTimes;t.securityWaitTimes=n,t.waitTime=n.isTemporarilyClosed?9999:n.queueTime??0}),T()},clearCache:T}}function f(t,o,n){const e=n[t],r=n[o];return i(e.lat,e.lng,r.lat,r.lng)}let a,h,p,g,m,y;const T=()=>{a={},h={},p={},g=new u,m=null,y={}};function b(t,o,n,e,i={},s={}){for(t.id===m&&y===JSON.stringify(s)||(T(),g.offerWithPriority(t.id,0),a[t.id]=0,p[t.id]=!0,m=t.id,y=JSON.stringify(s));!g.isEmpty()&&!p[o.id];){const t=g.poll();if(null==t)break;const o=n[t],l=a[o.id];for(let t=0;t<o.edges.length;t++){const n=o.edges[t];if(e.size>0&&e.has(n.dst))continue;if(p[n.dst])continue;if(s.requiresAccessibility&&!n.isAccessible)continue;const u=d(n),c=i;if(n.o&&c[n.o]){n.securityLane=c[n.o];const{type:t,id:o}=c[n.o],e=r(["selectedSecurityLanes",t],s);if(e&&!e.includes(o))continue}void 0===a[n.dst]?(h[n.dst]=o,a[n.dst]=l+u,g.offerWithPriority(n.dst,l+u)):a[n.dst]>l+u&&(a[n.dst]=l+u,h[n.dst]=o,g.raisePriority(n.dst,l+u))}p[o.id]=!0}if(!p[o.id])return null;const l=[];let u=o;for(;u;)l.push(u),u=h[u.id];return l.reverse()}function I(t,o,n,e){const r=o.substr(0,e),i=[];i.push(t+":"+l(l(r,"top"),"left")),i.push(t+":"+l(r,"top")),i.push(t+":"+l(l(r,"top"),"right")),i.push(t+":"+l(r,"left")),i.push(t+":"+r),i.push(t+":"+l(r,"right")),i.push(t+":"+l(l(r,"bottom"),"left")),i.push(t+":"+l(r,"bottom")),i.push(t+":"+l(l(r,"bottom"),"right"));const s=[];for(let t=0;t<i.length;t++){const o=n[i[t]];if(o)for(let t=0;t<o.length;t++)s.push(o[t])}return s}function v(t,o,n,e,r){const l=function(t,o,n){let e=I(t,o,n,8);return e.length>0?e:(e=I(t,o,n,7),e.length>0?e:null)}(t,s(o,n),e),u=l??[w(t,o,n,r)],d=[];for(let t=0;t<u.length;t++){const e=i(o,n,u[t].lat,u[t].lng);d.push([u[t],e])}d.sort(function(t,o){return t[1]-o[1]});const c=[];for(let t=0;t<d.length;t++){const o=d[t];o&&c.push(o[0])}return c[0]}function w(t,o,n,e){const r=Object.values(e).filter(o=>o.floorId===t).map(t=>[t,i(t.lat,t.lng,o,n)]);if(!r.length)throw Error(`findClosestNodeByFloor2 found no nodes on floor ${t}`);return E(r)}function S(t,o,n,e){const r=Object.values(e).filter(o=>o.ordinal===t).map(t=>[t,i(t.lat,t.lng,o,n)]);if(!r.length)throw Error(`findClosestNodeByOrdinal found no nodes on ordinal ${t}`);return E(r)}function E(t){let o=t[0];for(let n=1;n<t.length;n++){const e=t[n];e&&e[1]<o[1]&&(o=e)}return o[0]}export{c as createNavGraph,S as findClosestNodeByOrdinal,b as findShortestPath,d as getEdgeTraversalTime};
@@ -1 +1 @@
1
- import*as t from"ramda";import n from"zousan";import{buildStructuresLookup as o}from"../../../src/utils/buildStructureLookup.js";import{distance as e}from"../../../src/utils/geodesy.js";import{findRoute as i}from"./findRoute.js";import{createNavGraph as r}from"./navGraph.js";import{enrichDebugNavGraph as a}from"./navGraphDebug.js";import{buildSegments as s}from"./segmentBuilder.js";const u={SECURITY:"SecurityLane",IMMIGRATION:"ImmigrationLane"};function d(d,l){const p=d.log.sublog("wayfinder"),c=async()=>{d.bus.send("venueData/loadNavGraph")};let f=new n;d.bus.on("wayfinder/_getNavGraph",()=>f),d.bus.on("venueData/navGraphLoaded",async({navGraphData:t,structures:n})=>{const e=o(n),i=await m(),a=r(t,e.floorIdToOrdinal,e.floorIdToStructureId,i);f.resolve(a)}),d.bus.on("poi/setDynamicRouting",async({idValuesMap:t})=>{const n=await f,o=Object.values(t).filter(t=>t.position&&void 0!==t.position.floorId&&t.position.latitude&&t.position.longitude).map(t=>n.findClosestNode(t.position.floorId,t.position.latitude,t.position.longitude).id);n.addNodesToAvoid(o)});const m=async()=>{const n=await d.bus.get("poi/getByCategoryId",{categoryId:"security"});return t.pipe(t.map(y),t.filter(Boolean))(n)},y=n=>n.queue&&{type:t.path(["queue","queueType"],n),id:t.path(["queue","queueSubtype"],n)};d.bus.on("wayfinder/showNavLineFromPhysicalLocation",async({toEndpoint:t,selectedSecurityLanes:n=null,requiresAccessibility:o})=>async function(t,n,o){const e=await T({fromEndpoint:t,toEndpoint:n,options:o});if(e){const{segments:t}=e;o.primary&&d.bus.send("map/resetNavlineFeatures"),d.bus.send("map/showNavlineFeatures",{segments:t,category:o.primary?"primary":"alternative"})}return e}(await d.bus.getFirst("user/getPhysicalLocation"),t,{selectedSecurityLanes:n,requiresAccessibility:o,primary:!0}));const g=(t,n)=>d.bus.get("poi/getById",{id:t}).then(o=>{if(o&&o.position)return w(o,n);throw Error("Unknown POI ID "+t)});const h=["lat","lng","floorId","ordinal"],I=t.pipe(t.pick(h),t.keys,t.propEq(h.length,"length"),Boolean),w=(t,n)=>({lat:t.position.latitude,lng:t.position.longitude,floorId:t.position.floorId,ordinal:n(t.position.floorId),title:t.name});async function T({fromEndpoint:t,toEndpoint:n,options:o={}}){const e=await d.bus.get("poi/getAll")||{},r=Array.isArray(e)?e[0]:e,a=Object.values(r).filter(t=>t.category&&t.category.startsWith("security")),u=await d.bus.getFirst("directions/getPreferredUnits")||"meters";return f.then(async e=>{o.compareFindPaths=l.compareFindPaths;const r=i(e,t,n,o);if(!r)return null;const c=await d.bus.get("venueData/getFloorIdToNameMap"),f=await d.bus.get("venueData/getQueueTypes"),m=d.gt(),y=o.requiresAccessibility,{steps:g,segments:h}=s(r.waypoints,t,n,c,m,f,y,a,u);p.info("route",r);const I=Math.round(r.waypoints.reduce((t,{eta:n})=>t+n,0)),w=Math.round(r.waypoints.reduce((t,{distance:n})=>t+n,0));return{...r,segments:h,steps:g,time:I,distance:w}})}function b(n,o,e,i){let r=t.clone(n);return r=E(r,e,i),o&&o.length?{...r,transitTime:v(o,"transitTime"),distance:v(o,"distance")}:(r.distance="start"===i?O(r,e):O(e,r),r.transitTime=S(r.distance),r)}function v(n,o){return t.aperture(2,n).map(([n,o])=>{return(e=o.id,n=>t.find(t=>t.dst===e,n.edges))(n);var e}).map(t=>t?.[o]??0).reduce((t,n)=>t+n,0)}function E(t,n,o){return{...t,[o+"Information"]:{lat:n?.lat||n?.position?.latitude,lng:n?.lng||n?.position?.longitude,floorId:n?.floorId||n?.position?.floorId}}}function O(t,n){return e(n?.lat||n?.position?.latitude,n?.lng||n?.position?.longitude,t?.lat||t?.position?.latitude,t?.lng||t?.position?.longitude)}function S(t){return t/60}function L(n){const o=n.filter(t=>null!==t);return t.sortBy(t.propOr(1/0,"transitTime"),o)}function N(t,n){return t&&t.length?v(t,"transitTime"):S(n)}function P(t,n,o){return t&&t.length?v(t,"distance"):O(o,n)}return d.bus.on("wayfinder/getNavigationEndpoint",({ep:t})=>async function(t){return f.then(n=>{if(!t)throw Error("wayfinder: Invalid endpoint definition",t);if("number"==typeof t)return g(t,n.floorIdToOrdinal);if("string"==typeof t){if(t.match(/^\d+$/))return g(parseInt(t),n.floorIdToOrdinal);if(t.indexOf(",")>0){const[o,e,i,r]=t.split(",");if(!n.floorIdToStructureId(i))throw Error("Unknown floorId in endpoint: "+i);let a=r;return a||(a="Starting Point"),{lat:parseFloat(o),lng:parseFloat(e),ordinal:n.floorIdToOrdinal(i),floorId:i,title:a}}}if(I(t))return t;if(t.latitude)return{lat:t.latitude,lng:t.longitude,floorId:t.floorId,ordinal:n.floorIdToOrdinal(t.floorId),title:t.title};if(t.position&&t.name)return w(t,n.floorIdToOrdinal);throw Error("Invalid start or end point: "+t)})}(t)),d.bus.on("wayfinder/checkIfPathHasSecurity",({fromEndpoint:n,toEndpoint:o,options:e={}})=>f.then(r=>{e.compareFindPaths=l.compareFindPaths;const a=i(r,n,o,e);if(!a)return{routeExists:!1};const s=n=>Boolean(a.waypoints.find(t.pathEq(n,["securityLane","type"])));return{routeExists:!0,queues:a.waypoints.filter(n=>t.pathEq(u.SECURITY,["securityLane","type"],n)||t.pathEq(u.IMMIGRATION,["securityLane","type"],n)),hasSecurity:s(u.SECURITY),hasImmigration:s(u.IMMIGRATION)}})),d.bus.on("wayfinder/getRoute",T),d.bus.on("wayfinder/addPathTimeMultiple",async({pois:n,startLocation:o,options:e={}})=>o?f.then(i=>function(n,o,e,i){try{const r=t.clone(e),a=r.map(t=>w(t,n.floorIdToOrdinal)),s=n.findAllShortestPaths(i,a,o);return L(r.map((t,n)=>b(t,s[n],i,"start")))}catch(t){return p.error(t),e}}(i,e,n,o)):n),d.bus.on("wayfinder/multipointAddPathTimeMultiple",async({pois:n,startLocation:o,endLocation:e,currentLocation:i,options:r={}})=>o||e||i?f.then(a=>function(n,o,e,i,r,a){try{const s=i?w(i,n.floorIdToOrdinal):a,u=r?w(r,n.floorIdToOrdinal):null,d=t.clone(e),l=d.map(t=>w(t,n.floorIdToOrdinal));let p,c=[],f=[];return s&&(c=n.findAllShortestPaths(s,l,o)),u&&(f=function(t,n,o,e){const i=[];for(const r of n)i.push(t.findShortestPath(r,o,e));return i}(n,l,u,o)),p=s&&u?d.map((n,o)=>function(n,o,e,i,r){const a=P(o,i,n),s=P(e,n,r);if(!a||!s)return null;const u=N(o,a),d=N(e,s);let l=t.clone(n);return l=E(l,i,"start"),l=E(l,r,"end"),{...l,transitTime:u+d,distance:a+s,startInformation:{...l.startInformation,transitTime:u,distance:a},endInformation:{...l.endInformation,transitTime:d,distance:s}}}(n,c[o],f[o],s,u)):s?d.map((t,n)=>b(t,c[n],s,"start")):d.map((t,n)=>b(t,f[n],u,"end")),L(p)}catch(t){return p.error(t),e}}(a,r,n,o,e,i)):n),d.bus.on("venueData/loadNewVenue",()=>{f=new n,c()}),d.bus.on("poi/setDynamicData",({plugin:t,idValuesMap:n})=>{"security"===t&&f.then(t=>t.updateWithSecurityWaitTime(n))}),d.bus.on("wayfinder/getNavGraphFeatures",()=>f.then(({_nodes:t})=>a(t))),{init:c,internal:{resolveNavGraph:t=>f.resolve(t),prepareSecurityLanes:m}}}export{u as SecurityLaneType,d as create};
1
+ import*as t from"ramda";import n from"zousan";import{buildStructuresLookup as o}from"../../../src/utils/buildStructureLookup.js";import{distance as e}from"../../../src/utils/geodesy.js";import{findRoute as i}from"./findRoute.js";import{createNavGraph as r,getEdgeTraversalTime as a}from"./navGraph.js";import{enrichDebugNavGraph as s}from"./navGraphDebug.js";import{buildSegments as u}from"./segmentBuilder.js";const d=n=>o=>t.find(t=>t.dst===n,o.edges),l={SECURITY:"SecurityLane",IMMIGRATION:"ImmigrationLane"};function p(p,c){const f=p.log.sublog("wayfinder"),m=async()=>{p.bus.send("venueData/loadNavGraph")};let y=new n;p.bus.on("wayfinder/_getNavGraph",()=>y),p.bus.on("venueData/navGraphLoaded",async({navGraphData:t,structures:n})=>{const e=o(n),i=await g(),a=r(t,e.floorIdToOrdinal,e.floorIdToStructureId,i);y.resolve(a)}),p.bus.on("poi/setDynamicRouting",async({idValuesMap:t})=>{const n=await y,o=Object.values(t).filter(t=>t.position&&void 0!==t.position.floorId&&t.position.latitude&&t.position.longitude).map(t=>n.findClosestNode(t.position.floorId,t.position.latitude,t.position.longitude).id);n.addNodesToAvoid(o)});const g=async()=>{const n=await p.bus.get("poi/getByCategoryId",{categoryId:"security"});return t.pipe(t.map(h),t.filter(Boolean))(n)},h=n=>n.queue&&{type:t.path(["queue","queueType"],n),id:t.path(["queue","queueSubtype"],n)};p.bus.on("wayfinder/showNavLineFromPhysicalLocation",async({toEndpoint:t,selectedSecurityLanes:n=null,requiresAccessibility:o})=>async function(t,n,o){const e=await v({fromEndpoint:t,toEndpoint:n,options:o});if(e){const{segments:t}=e;o.primary&&p.bus.send("map/resetNavlineFeatures"),p.bus.send("map/showNavlineFeatures",{segments:t,category:o.primary?"primary":"alternative"})}return e}(await p.bus.getFirst("user/getPhysicalLocation"),t,{selectedSecurityLanes:n,requiresAccessibility:o,primary:!0}));const I=(t,n)=>p.bus.get("poi/getById",{id:t}).then(o=>{if(o&&o.position)return T(o,n);throw Error("Unknown POI ID "+t)});const w=["lat","lng","floorId","ordinal"],b=t.pipe(t.pick(w),t.keys,t.propEq(w.length,"length"),Boolean),T=(t,n)=>({lat:t.position.latitude,lng:t.position.longitude,floorId:t.position.floorId,ordinal:n(t.position.floorId),title:t.name});async function v({fromEndpoint:t,toEndpoint:n,options:o={}}){const e=await p.bus.get("poi/getAll")||{},r=Array.isArray(e)?e[0]:e,a=Object.values(r).filter(t=>t.category&&t.category.startsWith("security")),s=await p.bus.getFirst("directions/getPreferredUnits")||"meters";return y.then(async e=>{o.compareFindPaths=c.compareFindPaths;const r=i(e,t,n,o);if(!r)return null;const d=await p.bus.get("venueData/getFloorIdToNameMap"),l=await p.bus.get("venueData/getQueueTypes"),m=p.gt(),y=o.requiresAccessibility,{steps:g,segments:h}=u(r.waypoints,t,n,d,m,l,y,a,s);f.info("route",r);const I=Math.round(r.waypoints.reduce((t,{eta:n})=>t+n,0)),w=Math.round(r.waypoints.reduce((t,{distance:n})=>t+n,0));return{...r,segments:h,steps:g,time:I,distance:w}})}function E(n,o,e,i){let r=t.clone(n);return r=L(r,e,i),o&&o.length?{...r,transitTime:S(o),distance:O(o,"distance")}:(r.distance="start"===i?N(r,e):N(e,r),r.transitTime=P(r.distance),r)}function O(n,o){return t.aperture(2,n).map(([t,n])=>d(n.id)(t)).map(t=>t?.[o]??0).reduce((t,n)=>t+n,0)}function S(n){return t.aperture(2,n).map(([t,n])=>d(n.id)(t)).reduce((t,n)=>t+(n?a(n):0),0)}function L(t,n,o){return{...t,[o+"Information"]:{lat:n?.lat||n?.position?.latitude,lng:n?.lng||n?.position?.longitude,floorId:n?.floorId||n?.position?.floorId}}}function N(t,n){return e(n?.lat||n?.position?.latitude,n?.lng||n?.position?.longitude,t?.lat||t?.position?.latitude,t?.lng||t?.position?.longitude)}function P(t){return t/60}function q(n){const o=n.filter(t=>null!==t);return t.sortBy(t.propOr(1/0,"transitTime"),o)}function A(t,n){return t&&t.length?S(t):P(n)}function F(t,n,o){return t&&t.length?O(t,"distance"):N(o,n)}return p.bus.on("wayfinder/getNavigationEndpoint",({ep:t})=>async function(t){return y.then(n=>{if(!t)throw Error("wayfinder: Invalid endpoint definition",t);if("number"==typeof t)return I(t,n.floorIdToOrdinal);if("string"==typeof t){if(t.match(/^\d+$/))return I(parseInt(t),n.floorIdToOrdinal);if(t.indexOf(",")>0){const[o,e,i,r]=t.split(",");if(!n.floorIdToStructureId(i))throw Error("Unknown floorId in endpoint: "+i);let a=r;return a||(a="Starting Point"),{lat:parseFloat(o),lng:parseFloat(e),ordinal:n.floorIdToOrdinal(i),floorId:i,title:a}}}if(b(t))return t;if(t.latitude)return{lat:t.latitude,lng:t.longitude,floorId:t.floorId,ordinal:n.floorIdToOrdinal(t.floorId),title:t.title};if(t.position&&t.name)return T(t,n.floorIdToOrdinal);throw Error("Invalid start or end point: "+t)})}(t)),p.bus.on("wayfinder/checkIfPathHasSecurity",({fromEndpoint:n,toEndpoint:o,options:e={}})=>y.then(r=>{e.compareFindPaths=c.compareFindPaths;const a=i(r,n,o,e);if(!a)return{routeExists:!1};const s=n=>Boolean(a.waypoints.find(t.pathEq(n,["securityLane","type"])));return{routeExists:!0,queues:a.waypoints.filter(n=>t.pathEq(l.SECURITY,["securityLane","type"],n)||t.pathEq(l.IMMIGRATION,["securityLane","type"],n)),hasSecurity:s(l.SECURITY),hasImmigration:s(l.IMMIGRATION)}})),p.bus.on("wayfinder/getRoute",v),p.bus.on("wayfinder/addPathTimeMultiple",async({pois:n,startLocation:o,options:e={}})=>o?y.then(i=>function(n,o,e,i){try{const r=t.clone(e),a=r.map(t=>T(t,n.floorIdToOrdinal)),s=n.findAllShortestPaths(i,a,o);return q(r.map((t,n)=>E(t,s[n],i,"start")))}catch(t){return f.error(t),e}}(i,e,n,o)):n),p.bus.on("wayfinder/multipointAddPathTimeMultiple",async({pois:n,startLocation:o,endLocation:e,currentLocation:i,options:r={}})=>o||e||i?y.then(a=>function(n,o,e,i,r,a){try{const s=i?T(i,n.floorIdToOrdinal):a,u=r?T(r,n.floorIdToOrdinal):null,d=t.clone(e),l=d.map(t=>T(t,n.floorIdToOrdinal));let p,c=[],f=[];return s&&(c=n.findAllShortestPaths(s,l,o)),u&&(f=function(t,n,o,e){const i=[];for(const r of n)i.push(t.findShortestPath(r,o,e));return i}(n,l,u,o)),p=s&&u?d.map((n,o)=>function(n,o,e,i,r){const a=F(o,i,n),s=F(e,n,r);if(!a||!s)return null;const u=A(o,a),d=A(e,s);let l=t.clone(n);return l=L(l,i,"start"),l=L(l,r,"end"),{...l,transitTime:u+d,distance:a+s,startInformation:{...l.startInformation,transitTime:u,distance:a},endInformation:{...l.endInformation,transitTime:d,distance:s}}}(n,c[o],f[o],s,u)):s?d.map((t,n)=>E(t,c[n],s,"start")):d.map((t,n)=>E(t,f[n],u,"end")),q(p)}catch(t){return f.error(t),e}}(a,r,n,o,e,i)):n),p.bus.on("venueData/loadNewVenue",()=>{y=new n,m()}),p.bus.on("poi/setDynamicData",({plugin:t,idValuesMap:n})=>{"security"===t&&y.then(t=>t.updateWithSecurityWaitTime(n))}),p.bus.on("wayfinder/getNavGraphFeatures",()=>y.then(({_nodes:t})=>s(t))),{init:m,internal:{resolveNavGraph:t=>y.resolve(t),prepareSecurityLanes:g}}}export{l as SecurityLaneType,p as create};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atriusmaps-node-sdk",
3
- "version": "3.3.981",
3
+ "version": "3.3.982",
4
4
  "description": "This project provides an API to Atrius Personal Wayfinder maps within a Node environment. See the README.md for more information",
5
5
  "keywords": [
6
6
  "map",