proximiio-js-library 1.9.7 → 1.9.8

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.
package/README.md CHANGED
@@ -175,6 +175,7 @@ const map = new Proximiio.Map({
175
175
  },
176
176
  language: 'en', // optional, set default map language for poi features
177
177
  routeColor: '#000000', // optional, define route line color
178
+ forceFloorLevel: 0, // optional, define floor number if you want to force routes visible for single level
178
179
  });
179
180
  ```
180
181
 
@@ -494,6 +495,22 @@ map.getMapReadyListener().subscribe(ready => {
494
495
  });
495
496
  ```
496
497
 
498
+ ##### Set Features Highlight
499
+
500
+ Method for adding circle layer as a highlight for defined features.
501
+
502
+ ```
503
+ // @param features {string[]} array of feature ids to set highlight on, you can send empty array to remove highlights.
504
+ // @param color {string} highlight color, optional, default: '#000'.
505
+ // @param radius {number} highlight circle radius, optional, default: 50.
506
+ // @param blur {number} blur of the highlight circle, optional, default: 0.8.
507
+
508
+ map.getMapReadyListener().subscribe(ready => {
509
+ console.log('map ready', ready);
510
+ map.setFeaturesHighlight(['featureid']);
511
+ });
512
+ ```
513
+
497
514
  ##### Add New Feature
498
515
 
499
516
  Add new feature to map.
@@ -60,8 +60,8 @@ export class Wayfinding {
60
60
  const routableAreaFeatureList = featureList.filter(feature => feature.properties.routable && this.ROUTABLE_TYPE.includes(feature.geometry.type));
61
61
  let floorGeojsonMap = new Map();
62
62
  for (let level = minLevel; level <= maxLevel; level++) {
63
- let floorAreaFeature = routableAreaFeatureList.find(feature => feature.properties.level === level);
64
- floorGeojsonMap.set(level, turf.featureCollection(floorAreaFeature !== undefined ? [floorAreaFeature] : []));
63
+ let floorAreaFeature = routableAreaFeatureList.filter(feature => feature.properties.level === level);
64
+ floorGeojsonMap.set(level, turf.featureCollection(floorAreaFeature !== undefined ? floorAreaFeature : []));
65
65
  }
66
66
  this.floorList = floorGeojsonMap;
67
67
 
@@ -117,7 +117,7 @@ export class Wayfinding {
117
117
  let maxLevel = undefined;
118
118
 
119
119
  featureList.forEach(feature => {
120
- let level = feature.properties.level;
120
+ const level = feature.properties.level;
121
121
  if (minLevel === undefined || level < minLevel) {
122
122
  minLevel = level;
123
123
  }
@@ -125,17 +125,17 @@ export class Wayfinding {
125
125
  maxLevel = level;
126
126
  }
127
127
  if (feature.properties.levels !== undefined) {
128
- feature.properties.levels.forEach(level => {
129
- if (minLevel === undefined || level < minLevel) {
130
- minLevel = level;
128
+ feature.properties.levels.forEach(item => {
129
+ if (minLevel === undefined || item < minLevel) {
130
+ minLevel = item;
131
131
  }
132
- if (maxLevel === undefined || maxLevel < level) {
133
- maxLevel = level;
132
+ if (maxLevel === undefined || maxLevel < item) {
133
+ maxLevel = item;
134
134
  }
135
135
  });
136
136
  }
137
137
  });
138
- return { minLevel, maxLevel};
138
+ return { minLevel, maxLevel };
139
139
  }
140
140
 
141
141
  rebuildData() {
@@ -146,8 +146,8 @@ export class Wayfinding {
146
146
  let floorAreas = [];
147
147
 
148
148
  // Floor features == "walkable areas"
149
- floor.features.forEach((walkableArea, walkableAreaIndex) => {
150
- let wallLineStringList = turf.flatten(turf.polygonToLine(walkableArea)).features.map(feature => {return feature.geometry; });
149
+ floor.features.forEach(walkableArea => {
150
+ let wallLineStringList = turf.flatten(turf.polygonToLine(walkableArea)).features.map(feature => feature.geometry);
151
151
  // Floor wall lines, we wish to split to individual walls
152
152
  wallLineStringList.forEach(wallLineString => {
153
153
  let firstPoint;
@@ -160,6 +160,7 @@ export class Wayfinding {
160
160
  firstPoint = turf.point(wallLineString.coordinates[index]);
161
161
  firstPoint.properties.level = level;
162
162
  firstPoint.properties.neighbours = [];
163
+ firstPoint.properties.walkableAreaId = walkableArea.id;
163
164
  point = firstPoint;
164
165
  } else {
165
166
  point = nextPoint;
@@ -170,6 +171,7 @@ export class Wayfinding {
170
171
  nextPoint = turf.point(wallLineString.coordinates[index + 1]);
171
172
  nextPoint.properties.level = level;
172
173
  nextPoint.properties.neighbours = [];
174
+ nextPoint.properties.walkableAreaId = walkableArea.id;
173
175
  }
174
176
  point.properties.neighbours.push(nextPoint);
175
177
  nextPoint.properties.neighbours.push(point);
@@ -197,8 +199,8 @@ export class Wayfinding {
197
199
  let inAreaPoiList = this.accessibilityPoi
198
200
  .filter(poi => floorLevel === poi.properties.level)
199
201
  .filter(poi =>
200
- floorData.areas.filter(area => turf.booleanContains(area, poi)) .length > 0)
201
- ;
202
+ floorData.areas.filter(area => turf.booleanContains(area, poi)).length > 0);
203
+
202
204
  inAreaPoiList.forEach(poi => {
203
205
  // Generate points around POI to allow going around, but only if they are "within area
204
206
  let detourPointList = [
@@ -376,6 +378,8 @@ export class Wayfinding {
376
378
  intersectPoint.properties.level = segment[0].properties.level;
377
379
  intersectPoint.properties.neighbours = [];
378
380
  intersectPoint.properties.bordersArea = true;
381
+ intersectPoint.properties.walkableAreaId = walls[0][0].properties.walkableAreaId;
382
+
379
383
  // Intersect point inherits filters from both intersecting lines
380
384
  if (segmentFeature.properties.narrowPath) {
381
385
  intersectPoint.properties.narrowPath = true;
@@ -756,11 +760,13 @@ export class Wayfinding {
756
760
  if (previous === current || previous.geometry.coordinates[0] !== point.geometry.coordinates[0] || previous.geometry.coordinates[1] !== point.geometry.coordinates[1]) {
757
761
  let newPoint = this._copyPoint(point);
758
762
  newPoint.properties.level = current.properties.level;
763
+ newPoint.properties.walkableAreaId = current.properties.walkableAreaId;
764
+ newPoint.properties.bordersArea = current.properties.bordersArea;
759
765
  path.push(newPoint);
760
766
  previous = point;
761
767
  }
762
768
  });
763
- current = current.properties.cameFrom;
769
+ current = current.properties.cameFrom;
764
770
  } while (current != null);
765
771
 
766
772
  path.reverse();
@@ -778,7 +784,7 @@ export class Wayfinding {
778
784
  }
779
785
 
780
786
  let distanceAtoB = this._distance(pointA, pointB);
781
- // 70cm
787
+ // 50cm
782
788
  if (distanceAtoB < 0.5) {
783
789
  pointsToFilter.push(pointA);
784
790
  }
@@ -910,7 +916,25 @@ export class Wayfinding {
910
916
  * @return {[Feature<Point>]}
911
917
  * @private
912
918
  */
913
- runAStar(startPoint, endPoint) {
919
+ runAStar(startPoint, endPoint) {
920
+ const natural = this.calculatePath(startPoint, endPoint);
921
+ const reverse = this.calculatePath(endPoint, startPoint);
922
+
923
+ if (reverse === undefined || natural.length >= reverse.length) {
924
+ return natural
925
+ }
926
+
927
+ return reverse;
928
+ }
929
+
930
+ /**
931
+ *
932
+ * @param startPoint {Feature<Point>}
933
+ * @param endPoint {Feature<Point>}
934
+ * @return {[Feature<Point>]}
935
+ * @private
936
+ */
937
+ calculatePath(startPoint, endPoint) {
914
938
  this.clearData();
915
939
 
916
940
  this.nbLines = [];
@@ -927,7 +951,7 @@ export class Wayfinding {
927
951
  fixedStartPoint.properties.fscore = this._heuristic(fixedStartPoint, fixedEndPoint);
928
952
 
929
953
  while (openSet.length > 0) {
930
- let current = this._getMinFScore(openSet);
954
+ let current = this._getMinFScore(openSet, closedSet);
931
955
 
932
956
  // Unable to find best point to continue?
933
957
  if (current === null) {
@@ -936,10 +960,11 @@ export class Wayfinding {
936
960
 
937
961
  if (current === fixedEndPoint) {
938
962
  let finalPath = this.reconstructPath(current);
939
- if (fixedEndPoint !== endPoint && endPoint.properties.levels !== undefined && (!fixedEndPoint.properties.onCorridor || this._distance(fixedEndPoint, endPoint) > this.pathFixDistance)) {
963
+ if (fixedEndPoint !== endPoint && (!fixedEndPoint.properties.onCorridor || this._distance(fixedEndPoint, endPoint) > this.pathFixDistance)) {
940
964
  endPoint.properties.fixed = true
941
965
  finalPath.push(endPoint);
942
966
  }
967
+
943
968
  if (fixedStartPoint !== startPoint && (!fixedStartPoint.properties.onCorridor || this._distance(fixedStartPoint, startPoint) > this.pathFixDistance)) {
944
969
  startPoint.properties.fixed = true
945
970
  finalPath.unshift(startPoint);
@@ -953,26 +978,45 @@ export class Wayfinding {
953
978
 
954
979
  neighbours.forEach(n => this.nbLines.push(turf.lineString([current.geometry.coordinates, n.geometry.coordinates])));
955
980
 
956
- for (let nIndex in neighbours) {
957
- let neighbour = neighbours[nIndex];
958
- if (closedSet.indexOf(neighbour) > -1) {
959
- continue;
960
- }
961
-
962
- let tentativeGScore = current.properties.gscore + this._distance(current, neighbour);
963
- let gScoreNeighbour = neighbour.properties.gscore != null ? neighbour.properties.gscore : Infinity;
964
- if (tentativeGScore < gScoreNeighbour) {
965
- neighbour.properties.cameFrom = current;
966
- neighbour.properties.gscore = tentativeGScore + 0.2;
967
- neighbour.properties.fscore = tentativeGScore + this._heuristic(neighbour, fixedEndPoint);
968
- if (openSet.indexOf(neighbour) < 0) {
969
- openSet.push(neighbour);
981
+ neighbours.forEach( neighbour => {
982
+ if (closedSet.indexOf(neighbour) <= -1) {
983
+ let tentativeGScore = current.properties.gscore + this._distance(current, neighbour);
984
+ let gScoreNeighbour = neighbour.properties.gscore != null ? neighbour.properties.gscore : Infinity;
985
+
986
+ if (tentativeGScore < gScoreNeighbour) {
987
+ neighbour.properties.cameFrom = current;
988
+ neighbour.properties.gscore = tentativeGScore + 0.2;
989
+ neighbour.properties.fscore = tentativeGScore + this._heuristic(neighbour, fixedEndPoint);
990
+ if (openSet.indexOf(neighbour) < 0) {
991
+ openSet.push(neighbour);
992
+ }
970
993
  }
971
994
  }
995
+ });
996
+ }
997
+ return undefined;
998
+ }
999
+
1000
+ _checkIfCrossingTwoPolygon(current, neighbour) {
1001
+ const last = current.properties || {};
1002
+ const candidate = neighbour.properties || {};
1003
+
1004
+ if(candidate.walkableAreaId !== undefined && last.walkableAreaId !== undefined) {
1005
+ if (candidate.walkableAreaId !== last.walkableAreaId) {
1006
+ return true;
1007
+ }
972
1008
 
1009
+ if (candidate.bordersArea === undefined) {
1010
+ return true;
973
1011
  }
974
1012
  }
975
- return undefined;
1013
+
1014
+ if(last.walkableAreaId !== undefined && candidate.walkableAreaId === undefined) {
1015
+ if (candidate.isCorridorPoint === true) { return false; }
1016
+ return true;
1017
+ }
1018
+
1019
+ return false;
976
1020
  }
977
1021
 
978
1022
  /**
@@ -992,7 +1036,9 @@ export class Wayfinding {
992
1036
  let level = point.properties.level;
993
1037
  let revolvingDoorBlock = this.configuration.avoidRevolvingDoors && this._testAccessibilityPoiNeighbourhood(point, neighbourPoint, level, this.POI_TYPE.REVOLVING_DOOR);
994
1038
  let ticketGateBlock = this.configuration.avoidTicketGates && this._testAccessibilityPoiNeighbourhood(point, neighbourPoint, level, this.POI_TYPE.TICKET_GATE);
995
- return !revolvingDoorBlock && !ticketGateBlock;
1039
+ const isCrossingTwoPolygon = this._checkIfCrossingTwoPolygon(point, neighbourPoint);
1040
+
1041
+ return !revolvingDoorBlock && !ticketGateBlock && !isCrossingTwoPolygon;
996
1042
  });
997
1043
  } else {
998
1044
  // Gather neighbours over all levels
@@ -1003,12 +1049,13 @@ export class Wayfinding {
1003
1049
  let levelNeighbourMap = this.neighbourMap[level];
1004
1050
  if (levelNeighbourMap.hasOwnProperty(pointIndex)) {
1005
1051
  levelNeighbourMap[pointIndex].forEach(neighbourIndex => {
1006
- let neighbourPoint = points[neighbourIndex];
1052
+ const neighbourPoint = points[neighbourIndex];
1007
1053
 
1008
- let revolvingDoorBlock = this.configuration.avoidRevolvingDoors && this._testAccessibilityPoiNeighbourhood(point, neighbourPoint, level, this.POI_TYPE.REVOLVING_DOOR);
1009
- let ticketGateBlock = this.configuration.avoidTicketGates && this._testAccessibilityPoiNeighbourhood(point, neighbourPoint, level, this.POI_TYPE.TICKET_GATE);
1054
+ const revolvingDoorBlock = this.configuration.avoidRevolvingDoors && this._testAccessibilityPoiNeighbourhood(point, neighbourPoint, level, this.POI_TYPE.REVOLVING_DOOR);
1055
+ const ticketGateBlock = this.configuration.avoidTicketGates && this._testAccessibilityPoiNeighbourhood(point, neighbourPoint, level, this.POI_TYPE.TICKET_GATE);
1056
+ const isCrossingTwoPolygon = this._checkIfCrossingTwoPolygon(point, neighbourPoint);
1010
1057
 
1011
- if (!neighbours.includes(neighbourPoint) && (!revolvingDoorBlock && !ticketGateBlock)) {
1058
+ if (!neighbours.includes(neighbourPoint) && (!revolvingDoorBlock && !ticketGateBlock) && !isCrossingTwoPolygon) {
1012
1059
  neighbours.push(neighbourPoint);
1013
1060
  }
1014
1061
  });
@@ -1022,10 +1069,11 @@ export class Wayfinding {
1022
1069
  || (point.properties.fixedPointMap != undefined && point.properties.fixedPointMap.has(endPoint.properties.level))
1023
1070
  ) {
1024
1071
 
1025
- let revolvingDoorBlock = this.configuration.avoidRevolvingDoors && this._testAccessibilityPoiNeighbourhood(point, endPoint, endPoint.properties.level, this.POI_TYPE.REVOLVING_DOOR);
1026
- let ticketGateBlock = this.configuration.avoidTicketGates && this._testAccessibilityPoiNeighbourhood(point, endPoint, endPoint.properties.level, this.POI_TYPE.TICKET_GATE);
1072
+ const revolvingDoorBlock = this.configuration.avoidRevolvingDoors && this._testAccessibilityPoiNeighbourhood(point, endPoint, endPoint.properties.level, this.POI_TYPE.REVOLVING_DOOR);
1073
+ const ticketGateBlock = this.configuration.avoidTicketGates && this._testAccessibilityPoiNeighbourhood(point, endPoint, endPoint.properties.level, this.POI_TYPE.TICKET_GATE);
1074
+ const isCrossingTwoPolygon = this._checkIfCrossingTwoPolygon(point, endPoint);
1027
1075
 
1028
- if (!revolvingDoorBlock && !ticketGateBlock) {
1076
+ if (!revolvingDoorBlock && !ticketGateBlock && !isCrossingTwoPolygon) {
1029
1077
 
1030
1078
  // Endpoint is fixed on corridor
1031
1079
  if (endPoint.properties.onCorridor) {
@@ -1066,6 +1114,7 @@ export class Wayfinding {
1066
1114
  } else if (this.configuration.avoidHills && neighbour.properties.hill) {
1067
1115
  return false;
1068
1116
  }
1117
+
1069
1118
  return true;
1070
1119
  });
1071
1120
  }
@@ -1352,14 +1401,7 @@ export class Wayfinding {
1352
1401
  }
1353
1402
 
1354
1403
  _testIdenticalPointInList(point, pointList) {
1355
- let pointCoordinates = point.geometry.coordinates;
1356
- for (let index in pointList) {
1357
- let proposedPointCoordinates = pointList[index].geometry.coordinates;
1358
- if (proposedPointCoordinates[0] === pointCoordinates[0] && proposedPointCoordinates[1] === pointCoordinates[1]) {
1359
- return true;
1360
- }
1361
- }
1362
- return false;
1404
+ return pointList.find((list) => list.geometry.coordinates[0] === point.geometry.coordinates[0] && list.geometry.coordinates[1] === point.geometry.coordinates[1]) !== undefined
1363
1405
  }
1364
1406
 
1365
1407
  /**
@@ -1367,16 +1409,24 @@ export class Wayfinding {
1367
1409
  * @param pointSet {[Feature<Point>]}
1368
1410
  * @returns {Feature<Point>}
1369
1411
  */
1370
- _getMinFScore(pointSet) {
1412
+ _getMinFScore(pointSet, previous) {
1371
1413
  let bestPoint = null;
1372
1414
  let bestScore = Infinity;
1373
- for (let index in pointSet) {
1374
- let point = pointSet[index];
1375
- if (point.properties.fscore < bestScore) {
1415
+
1416
+ const lastWalkableAreaId = (previous.slice(-1).properties || {}).walkableAreaId;
1417
+ const penultimateWalkableAreaId = (previous.slice(-2).properties || {}).walkableAreaId;
1418
+
1419
+ const closedWalkable = penultimateWalkableAreaId !== undefined && lastWalkableAreaId === penultimateWalkableAreaId;
1420
+
1421
+ pointSet.forEach(point => {
1422
+ const properties = point.properties;
1423
+
1424
+ if (properties.fscore < bestScore) {//} && (closedWalkable || (!closedWalkable && properties.walkableAreaId === lastWalkableAreaId))) {
1376
1425
  bestPoint = point;
1377
- bestScore = point.properties.fscore;
1426
+ bestScore = properties.fscore;
1427
+
1378
1428
  }
1379
- }
1429
+ });
1380
1430
  return bestPoint;
1381
1431
  }
1382
1432
 
@@ -1434,12 +1484,10 @@ export class Wayfinding {
1434
1484
  * @private
1435
1485
  */
1436
1486
  _getFixEndPoint(endPoint, startPointLevel) {
1437
- // LC
1438
1487
  let lc = this.levelChangerList.find(it => it.id === endPoint.id);
1439
- // if (lc !== undefined) return lc;
1440
1488
  if (lc !== undefined && lc.properties.fixedPointMap !== undefined) {
1441
1489
  let nearestLevel = undefined;
1442
- lc.properties.fixedPointMap.forEach((fixedPoint, level) => {
1490
+ lc.properties.fixedPointMap.forEach((_, level) => {
1443
1491
  if (nearestLevel === undefined || Math.abs(nearestLevel - startPointLevel) > Math.abs(level - startPointLevel)) {
1444
1492
  nearestLevel = level;
1445
1493
  }
@@ -1454,20 +1502,25 @@ export class Wayfinding {
1454
1502
  let floorData = this.floorData.get(point.properties.level);
1455
1503
 
1456
1504
  // If point is located without accessible area, do nothing
1457
- let areaList = floorData.areas;
1458
- for (let index in areaList) {
1459
- let polygon = areaList[index];
1505
+ let pointFound = undefined;
1506
+ floorData.areas.forEach(polygon => {
1460
1507
  if (turf.booleanContains(polygon, point)) {
1461
- return point;
1508
+ pointFound = point;
1509
+ return;
1462
1510
  }
1511
+ });
1512
+ if (pointFound !== undefined) {
1513
+ return pointFound;
1463
1514
  }
1464
1515
 
1516
+
1465
1517
  // Find nearest wall to stick to
1466
1518
  let bestWall = null;
1467
1519
  let bestWallDistance = Infinity;
1520
+
1468
1521
  floorData.wallFeatures.forEach(wall => {
1469
- let distance = turf.pointToLineDistance(point.geometry.coordinates, wall, {units: this.UNIT_TYPE});
1470
- if (distance < bestWallDistance) {
1522
+ let distance = turf.pointToLineDistance(point.geometry.coordinates, wall, { units: this.UNIT_TYPE });
1523
+ if (distance <= bestWallDistance) {
1471
1524
  bestWall = wall;
1472
1525
  bestWallDistance = distance;
1473
1526
  }
@@ -1545,7 +1598,6 @@ export class Wayfinding {
1545
1598
 
1546
1599
  // Return created point
1547
1600
  return fixedPoint;
1548
-
1549
1601
  }
1550
1602
  }
1551
1603
 
@@ -84,6 +84,7 @@ interface Options {
84
84
  };
85
85
  language?: string;
86
86
  routeColor?: string;
87
+ forceFloorLevel?: number;
87
88
  }
88
89
  interface PaddingOptions {
89
90
  bottom: number;
@@ -135,6 +136,7 @@ export declare class Map {
135
136
  private onSetKiosk;
136
137
  private initGeoLocation;
137
138
  private initDirectionIcon;
139
+ private onSetFeaturesHighlight;
138
140
  private initAnimatedRoute;
139
141
  private initRasterTiles;
140
142
  private initPolygons;
@@ -833,5 +835,21 @@ export declare class Map {
833
835
  * });
834
836
  */
835
837
  toggleRasterFloorplans(): void;
838
+ /**
839
+ * Method for adding circle layer as a highlight for defined features
840
+ * @memberof Map
841
+ * @name setFeaturesHighlight
842
+ * @param features {string[]} feature id to set highlight on, you can send empty array to remove highlights.
843
+ * @param color {string} highlight color, optional.
844
+ * @param radius {number} highlight circle radius, optional.
845
+ * @param blur {number} blur of the highlight circle, optional.
846
+ * @example
847
+ * const map = new Proximiio.Map();
848
+ * map.getMapReadyListener().subscribe(ready => {
849
+ * console.log('map ready', ready);
850
+ * map.setFeaturesHighlight(['featureid']);
851
+ * });
852
+ */
853
+ setFeaturesHighlight(features: string[], color?: string, radius?: number, blur?: number): void;
836
854
  }
837
855
  export {};
@@ -331,7 +331,7 @@ var Map = /** @class */ (function () {
331
331
  }
332
332
  routingSymbolsLayer = map.getLayer('proximiio-routing-symbols');
333
333
  if (routingSymbolsLayer) {
334
- routingSymbolsLayer.filter.push(['!=', ['get', 'type'], 'poi-custom']);
334
+ routingSymbolsLayer.filter.push(['match', ['get', 'type'], ['poi', 'poi-custom'], false, true]);
335
335
  this.state.style.getLayer('proximiio-routing-symbols').filter = routingSymbolsLayer.filter;
336
336
  map.setFilter('proximiio-routing-symbols', routingSymbolsLayer.filter);
337
337
  }
@@ -525,6 +525,52 @@ var Map = /** @class */ (function () {
525
525
  });
526
526
  }
527
527
  };
528
+ Map.prototype.onSetFeaturesHighlight = function (features, color, radius, blur) {
529
+ var map = this.map;
530
+ var featuresToHiglight = this.state.allFeatures.features.filter(function (f) {
531
+ return features.includes(f.id || f.properties.id);
532
+ });
533
+ var poisIconsLayer = this.map.getLayer('proximiio-pois-icons');
534
+ var poisIconsImageSize = this.map.getLayoutProperty('proximiio-pois-icons', 'icon-size');
535
+ if (map) {
536
+ if (!map.getLayer('highlight-icon-layer')) {
537
+ this.state.style.addLayer({
538
+ id: 'highlight-icon-layer',
539
+ type: 'circle',
540
+ source: 'highlight-icon-source',
541
+ minzoom: poisIconsLayer.minzoom,
542
+ maxzoom: poisIconsLayer.maxzoom,
543
+ paint: {
544
+ 'circle-radius': poisIconsImageSize[0] === 'interpolate'
545
+ ? [
546
+ poisIconsImageSize[0],
547
+ poisIconsImageSize[1],
548
+ poisIconsImageSize[2],
549
+ poisIconsImageSize[3],
550
+ poisIconsImageSize[4] * (radius ? radius : 50),
551
+ poisIconsImageSize[5],
552
+ poisIconsImageSize[6] * (radius ? radius : 50),
553
+ ]
554
+ : radius,
555
+ 'circle-color': color ? color : '#000',
556
+ 'circle-blur': blur !== null && blur !== undefined ? blur : 0.8,
557
+ },
558
+ filter: ['all', ['==', ['to-number', ['get', 'level']], this.state.floor.level]],
559
+ }, this.defaultOptions.initPolygons ? 'shop-custom' : 'proximiio-shop');
560
+ }
561
+ if (!map.getSource('highlight-icon-source')) {
562
+ this.state.style.addSource('highlight-icon-source', {
563
+ type: 'geojson',
564
+ data: {
565
+ type: 'FeatureCollection',
566
+ features: [],
567
+ },
568
+ });
569
+ }
570
+ this.state.style.sources['highlight-icon-source'].data.features = featuresToHiglight ? featuresToHiglight : [];
571
+ this.map.setStyle(this.state.style);
572
+ }
573
+ };
528
574
  Map.prototype.initAnimatedRoute = function () {
529
575
  if (this.map) {
530
576
  this.state.style.addSource('route-point', {
@@ -586,7 +632,7 @@ var Map = /** @class */ (function () {
586
632
  ? this.defaultOptions.rasterTilesOptions.beforeLayer
587
633
  : metadata['proximiio:raster:beforelayer']
588
634
  ? metadata['proximiio:raster:beforelayer']
589
- : 'proximiio-shop');
635
+ : 'osm-country_label-en');
590
636
  }
591
637
  };
592
638
  Map.prototype.initPolygons = function () {
@@ -1302,6 +1348,7 @@ var Map = /** @class */ (function () {
1302
1348
  Map.prototype.onRouteChange = function (event) {
1303
1349
  return __awaiter(this, void 0, void 0, function () {
1304
1350
  var routeStart, textNavigation, logger, style;
1351
+ var _this = this;
1305
1352
  return __generator(this, function (_a) {
1306
1353
  switch (_a.label) {
1307
1354
  case 0:
@@ -1320,6 +1367,14 @@ var Map = /** @class */ (function () {
1320
1367
  if (this.defaultOptions.animatedRoute) {
1321
1368
  this.addAnimatedRouteFeatures();
1322
1369
  }
1370
+ if (this.defaultOptions.forceFloorLevel !== null && this.defaultOptions.forceFloorLevel !== undefined) {
1371
+ this.routingSource.data.features = this.routingSource.data.features.map(function (feature) {
1372
+ if (feature.properties.level !== _this.defaultOptions.forceFloorLevel) {
1373
+ feature.properties.level = _this.defaultOptions.forceFloorLevel;
1374
+ }
1375
+ return feature;
1376
+ });
1377
+ }
1323
1378
  this.centerOnRoute(routeStart);
1324
1379
  this.onRouteFoundListener.next({
1325
1380
  route: this.routingSource.route,
@@ -1574,6 +1629,11 @@ var Map = /** @class */ (function () {
1574
1629
  map.setFilter('route-point', filter);
1575
1630
  this.state.style.getLayer('route-point').filter = filter;
1576
1631
  }
1632
+ if (map.getLayer('highlight-icon-layer')) {
1633
+ var filter = ['all', ['==', ['to-number', ['get', 'level']], floor.level]];
1634
+ map.setFilter('highlight-icon-layer', filter);
1635
+ this.state.style.getLayer('highlight-icon-layer').filter = filter;
1636
+ }
1577
1637
  }
1578
1638
  this.state = __assign(__assign({}, this.state), { floor: floor, style: this.state.style });
1579
1639
  this.updateCluster();
@@ -2655,6 +2715,24 @@ var Map = /** @class */ (function () {
2655
2715
  Map.prototype.toggleRasterFloorplans = function () {
2656
2716
  this.onToggleRasterFloorplans();
2657
2717
  };
2718
+ /**
2719
+ * Method for adding circle layer as a highlight for defined features
2720
+ * @memberof Map
2721
+ * @name setFeaturesHighlight
2722
+ * @param features {string[]} feature id to set highlight on, you can send empty array to remove highlights.
2723
+ * @param color {string} highlight color, optional.
2724
+ * @param radius {number} highlight circle radius, optional.
2725
+ * @param blur {number} blur of the highlight circle, optional.
2726
+ * @example
2727
+ * const map = new Proximiio.Map();
2728
+ * map.getMapReadyListener().subscribe(ready => {
2729
+ * console.log('map ready', ready);
2730
+ * map.setFeaturesHighlight(['featureid']);
2731
+ * });
2732
+ */
2733
+ Map.prototype.setFeaturesHighlight = function (features, color, radius, blur) {
2734
+ this.onSetFeaturesHighlight(features, color, radius, blur);
2735
+ };
2658
2736
  return Map;
2659
2737
  }());
2660
2738
  exports.Map = Map;