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 +17 -0
- package/assets/wayfinding.js +117 -65
- package/lib/components/map/main.d.ts +18 -0
- package/lib/components/map/main.js +80 -2
- package/lib/proximiio.js +1 -1
- package/package.json +1 -1
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.
|
package/assets/wayfinding.js
CHANGED
|
@@ -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.
|
|
64
|
-
floorGeojsonMap.set(level, turf.featureCollection(floorAreaFeature !== undefined ?
|
|
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
|
-
|
|
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(
|
|
129
|
-
if (minLevel === undefined ||
|
|
130
|
-
minLevel =
|
|
128
|
+
feature.properties.levels.forEach(item => {
|
|
129
|
+
if (minLevel === undefined || item < minLevel) {
|
|
130
|
+
minLevel = item;
|
|
131
131
|
}
|
|
132
|
-
if (maxLevel === undefined || maxLevel <
|
|
133
|
-
maxLevel =
|
|
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(
|
|
150
|
-
let wallLineStringList = turf.flatten(turf.polygonToLine(walkableArea)).features.map(feature =>
|
|
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))
|
|
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 =
|
|
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
|
-
//
|
|
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
|
-
|
|
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 &&
|
|
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
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1052
|
+
const neighbourPoint = points[neighbourIndex];
|
|
1007
1053
|
|
|
1008
|
-
|
|
1009
|
-
|
|
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
|
-
|
|
1026
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
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 =
|
|
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((
|
|
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
|
|
1458
|
-
|
|
1459
|
-
let polygon = areaList[index];
|
|
1505
|
+
let pointFound = undefined;
|
|
1506
|
+
floorData.areas.forEach(polygon => {
|
|
1460
1507
|
if (turf.booleanContains(polygon, point)) {
|
|
1461
|
-
|
|
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
|
|
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(['
|
|
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
|
-
: '
|
|
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;
|