@mapvx/web-js 3.1.0-dev.1 → 3.1.0-dev.3
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/dist/cjs/controllers/markerLayoutController.js +337 -0
- package/dist/cjs/controllers/markerLayoutController.js.map +1 -0
- package/dist/cjs/controllers/routeController.js +13 -0
- package/dist/cjs/controllers/routeController.js.map +1 -1
- package/dist/cjs/domain/models/mapConfig.js +13 -1
- package/dist/cjs/domain/models/mapConfig.js.map +1 -1
- package/dist/cjs/domain/models/marker.js +147 -82
- package/dist/cjs/domain/models/marker.js.map +1 -1
- package/dist/cjs/index.js +2 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/logger/sentry.js +1 -1
- package/dist/cjs/map/map.js +41 -3
- package/dist/cjs/map/map.js.map +1 -1
- package/dist/cjs/utils/mapvxHostname.js +4 -3
- package/dist/cjs/utils/mapvxHostname.js.map +1 -1
- package/dist/es/config/sdkConfig.d.ts +1 -1
- package/dist/es/controllers/markerLayoutController.d.ts +140 -0
- package/dist/es/controllers/markerLayoutController.d.ts.map +1 -0
- package/dist/es/controllers/markerLayoutController.js +329 -0
- package/dist/es/controllers/markerLayoutController.js.map +1 -0
- package/dist/es/controllers/routeController.d.ts +7 -0
- package/dist/es/controllers/routeController.d.ts.map +1 -1
- package/dist/es/controllers/routeController.js +13 -0
- package/dist/es/controllers/routeController.js.map +1 -1
- package/dist/es/domain/models/mapConfig.d.ts +73 -0
- package/dist/es/domain/models/mapConfig.d.ts.map +1 -1
- package/dist/es/domain/models/mapConfig.js +12 -0
- package/dist/es/domain/models/mapConfig.js.map +1 -1
- package/dist/es/domain/models/marker.d.ts +232 -1
- package/dist/es/domain/models/marker.d.ts.map +1 -1
- package/dist/es/domain/models/marker.js +146 -82
- package/dist/es/domain/models/marker.js.map +1 -1
- package/dist/es/index.d.ts +2 -2
- package/dist/es/index.d.ts.map +1 -1
- package/dist/es/index.js +1 -1
- package/dist/es/index.js.map +1 -1
- package/dist/es/logger/sentry.js +1 -1
- package/dist/es/map/map.d.ts +15 -1
- package/dist/es/map/map.d.ts.map +1 -1
- package/dist/es/map/map.js +42 -4
- package/dist/es/map/map.js.map +1 -1
- package/dist/es/utils/mapvxHostname.d.ts +3 -2
- package/dist/es/utils/mapvxHostname.d.ts.map +1 -1
- package/dist/es/utils/mapvxHostname.js +4 -3
- package/dist/es/utils/mapvxHostname.js.map +1 -1
- package/dist/umd/index.js +832 -133
- package/dist/umd/index.js.map +1 -1
- package/dist/umd/styles.css +45 -19
- package/dist/umd/styles.css.map +1 -1
- package/package.json +1 -1
package/dist/umd/index.js
CHANGED
|
@@ -281,6 +281,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
281
281
|
CIRCLE_DEFAULTS: () => (/* reexport */ CIRCLE_DEFAULTS),
|
|
282
282
|
CacheManager: () => (/* reexport */ CacheManager),
|
|
283
283
|
DEFAULT_CACHE_CONFIGS: () => (/* reexport */ DEFAULT_CACHE_CONFIGS),
|
|
284
|
+
DEFAULT_MARKER_LAYOUT_CONFIG: () => (/* reexport */ DEFAULT_MARKER_LAYOUT_CONFIG),
|
|
284
285
|
DEFAULT_MAX_STORAGE_BYTES: () => (/* reexport */ DEFAULT_MAX_STORAGE_BYTES),
|
|
285
286
|
DEFAULT_TILE_CACHE_CONFIG: () => (/* reexport */ DEFAULT_TILE_CACHE_CONFIG),
|
|
286
287
|
FetchHttpClient: () => (/* reexport */ FetchHttpClient),
|
|
@@ -11239,7 +11240,7 @@ const extractSafariExtensionDetails = (func, filename) => {
|
|
|
11239
11240
|
// exists only for the type-checker, so in the ES/CJS builds the identifier is
|
|
11240
11241
|
// genuinely absent and a direct comparison throws ReferenceError at module load.
|
|
11241
11242
|
// `typeof` is the only safe way to probe a possibly-undeclared global.
|
|
11242
|
-
var sentry_SDK_VERSION = false ? 0 : "3.1.0-dev.
|
|
11243
|
+
var sentry_SDK_VERSION = false ? 0 : "3.1.0-dev.3";
|
|
11243
11244
|
var DSN = false ? 0 : "https://872f598f020e3cd73a0933b562d24c81@sentry.mapvx.app/5";
|
|
11244
11245
|
|
|
11245
11246
|
/**
|
|
@@ -11875,6 +11876,10 @@ function getBoundingBox(points) {
|
|
|
11875
11876
|
return [southwest, northeast];
|
|
11876
11877
|
}
|
|
11877
11878
|
;// ./src/domain/models/marker.ts
|
|
11879
|
+
function marker_typeof(o) { "@babel/helpers - typeof"; return marker_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, marker_typeof(o); }
|
|
11880
|
+
function marker_ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
11881
|
+
function marker_objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? marker_ownKeys(Object(t), !0).forEach(function (r) { marker_defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : marker_ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
11882
|
+
function marker_defineProperty(e, r, t) { return (r = marker_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
11878
11883
|
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
|
|
11879
11884
|
function _possibleConstructorReturn(t, e) { if (e && ("object" == marker_typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); }
|
|
11880
11885
|
function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; }
|
|
@@ -11882,7 +11887,6 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
|
|
|
11882
11887
|
function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
|
|
11883
11888
|
function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
|
|
11884
11889
|
function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
|
|
11885
|
-
function marker_typeof(o) { "@babel/helpers - typeof"; return marker_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, marker_typeof(o); }
|
|
11886
11890
|
function marker_classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
|
|
11887
11891
|
function marker_defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, marker_toPropertyKey(o.key), o); } }
|
|
11888
11892
|
function marker_createClass(e, r, t) { return r && marker_defineProperties(e.prototype, r), t && marker_defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
|
|
@@ -11917,6 +11921,22 @@ var TextPosition = /*#__PURE__*/function (TextPosition) {
|
|
|
11917
11921
|
return TextPosition;
|
|
11918
11922
|
}({});
|
|
11919
11923
|
|
|
11924
|
+
/**
|
|
11925
|
+
* Fallback icon width/height, in pixels, used whenever a marker is created
|
|
11926
|
+
* without explicit `iconProperties`.
|
|
11927
|
+
*
|
|
11928
|
+
* @group Markers
|
|
11929
|
+
*/
|
|
11930
|
+
var DEFAULT_ICON_SIZE_PX = 40;
|
|
11931
|
+
|
|
11932
|
+
/**
|
|
11933
|
+
* Fallback maximum label width, in pixels, used whenever neither the marker
|
|
11934
|
+
* nor the map's `markerLayout` configuration specifies one.
|
|
11935
|
+
*
|
|
11936
|
+
* @group Markers
|
|
11937
|
+
*/
|
|
11938
|
+
var DEFAULT_MAX_LABEL_WIDTH_PX = 200;
|
|
11939
|
+
|
|
11920
11940
|
/**
|
|
11921
11941
|
* Alignment options for marker rotation and pitch behavior.
|
|
11922
11942
|
* Controls how the marker responds to map rotation and pitch changes.
|
|
@@ -11961,6 +11981,7 @@ var TextPosition = /*#__PURE__*/function (TextPosition) {
|
|
|
11961
11981
|
*
|
|
11962
11982
|
* @group Markers
|
|
11963
11983
|
*/
|
|
11984
|
+
|
|
11964
11985
|
/**
|
|
11965
11986
|
* Utility class for creating and manipulating marker elements on a map.
|
|
11966
11987
|
* Provides static methods for marker element creation and styling.
|
|
@@ -11990,75 +12011,55 @@ var MarkerUtils = /*#__PURE__*/function () {
|
|
|
11990
12011
|
var markerContainer = document.createElement("div");
|
|
11991
12012
|
|
|
11992
12013
|
// Configure specific marker dimensions
|
|
11993
|
-
var iconWidth = (_marker$iconPropertie = (_marker$iconPropertie2 = marker.iconProperties) === null || _marker$iconPropertie2 === void 0 ? void 0 : _marker$iconPropertie2.width) !== null && _marker$iconPropertie !== void 0 ? _marker$iconPropertie :
|
|
11994
|
-
var iconHeight = (_marker$iconPropertie3 = (_marker$iconPropertie4 = marker.iconProperties) === null || _marker$iconPropertie4 === void 0 ? void 0 : _marker$iconPropertie4.height) !== null && _marker$iconPropertie3 !== void 0 ? _marker$iconPropertie3 :
|
|
12014
|
+
var iconWidth = (_marker$iconPropertie = (_marker$iconPropertie2 = marker.iconProperties) === null || _marker$iconPropertie2 === void 0 ? void 0 : _marker$iconPropertie2.width) !== null && _marker$iconPropertie !== void 0 ? _marker$iconPropertie : DEFAULT_ICON_SIZE_PX;
|
|
12015
|
+
var iconHeight = (_marker$iconPropertie3 = (_marker$iconPropertie4 = marker.iconProperties) === null || _marker$iconPropertie4 === void 0 ? void 0 : _marker$iconPropertie4.height) !== null && _marker$iconPropertie3 !== void 0 ? _marker$iconPropertie3 : DEFAULT_ICON_SIZE_PX;
|
|
11995
12016
|
|
|
11996
|
-
// Apply base class
|
|
12017
|
+
// Apply base class. The container's own box is always the icon's box (or
|
|
12018
|
+
// the custom `element`'s natural box) — the label is positioned
|
|
12019
|
+
// absolutely (see .text-container in styles.css) so it never affects
|
|
12020
|
+
// this box, which is exactly what MapLibre anchors the marker to.
|
|
11997
12021
|
markerContainer.className = "mapvx-marker";
|
|
11998
|
-
|
|
11999
|
-
// Configure classes and dimensions based on text presence
|
|
12000
|
-
if (marker.text) {
|
|
12001
|
-
// If text exists, adjust layout according to position
|
|
12002
|
-
switch (marker.textPosition) {
|
|
12003
|
-
case TextPosition.top:
|
|
12004
|
-
case TextPosition.bottom:
|
|
12005
|
-
markerContainer.classList.add("text-column");
|
|
12006
|
-
markerContainer.style.width = "".concat(Math.max(iconWidth, 200), "px");
|
|
12007
|
-
markerContainer.style.height = "auto";
|
|
12008
|
-
break;
|
|
12009
|
-
case TextPosition.left:
|
|
12010
|
-
case TextPosition.right:
|
|
12011
|
-
default:
|
|
12012
|
-
markerContainer.classList.add("text-row");
|
|
12013
|
-
markerContainer.style.width = "auto";
|
|
12014
|
-
markerContainer.style.height = "".concat(iconHeight, "px");
|
|
12015
|
-
break;
|
|
12016
|
-
}
|
|
12017
|
-
} else {
|
|
12018
|
-
// No text, use fixed icon dimensions as in official example
|
|
12019
|
-
markerContainer.classList.add("no-text");
|
|
12020
|
-
markerContainer.style.width = "".concat(iconWidth, "px");
|
|
12021
|
-
markerContainer.style.height = "".concat(iconHeight, "px");
|
|
12022
|
-
}
|
|
12023
12022
|
markerContainer.addEventListener("click", function () {
|
|
12024
12023
|
var _marker$onClick;
|
|
12025
12024
|
(_marker$onClick = marker.onClick) === null || _marker$onClick === void 0 || _marker$onClick.call(marker);
|
|
12026
12025
|
});
|
|
12026
|
+
|
|
12027
|
+
// Custom element replaces icon entirely; the label (if any) still gets
|
|
12028
|
+
// appended, positioned absolutely relative to it.
|
|
12027
12029
|
if (marker.element) {
|
|
12030
|
+
// Only force a box when the caller declared the footprint. Otherwise
|
|
12031
|
+
// the container is left to size itself to the custom element, and
|
|
12032
|
+
// automatic label collision avoidance measures that real box from the
|
|
12033
|
+
// DOM instead of assuming the default icon size — see
|
|
12034
|
+
// {@link MarkerAttribute.measureIconFromDom}.
|
|
12035
|
+
if (marker.iconProperties) {
|
|
12036
|
+
markerContainer.style.width = "".concat(iconWidth, "px");
|
|
12037
|
+
markerContainer.style.height = "".concat(iconHeight, "px");
|
|
12038
|
+
}
|
|
12028
12039
|
markerContainer.appendChild(marker.element);
|
|
12029
|
-
return this.setAndCreateText(marker, markerContainer
|
|
12040
|
+
return this.setAndCreateText(marker, markerContainer);
|
|
12030
12041
|
}
|
|
12031
|
-
|
|
12032
|
-
|
|
12042
|
+
markerContainer.style.width = "".concat(iconWidth, "px");
|
|
12043
|
+
markerContainer.style.height = "".concat(iconHeight, "px");
|
|
12033
12044
|
var iconElement = this.createIconElement(marker, iconWidth, iconHeight);
|
|
12034
|
-
|
|
12035
|
-
|
|
12036
|
-
// Add elements in correct order
|
|
12037
|
-
if (marker.textPosition === TextPosition.top || marker.textPosition === TextPosition.left) {
|
|
12038
|
-
if (textElement) markerContainer.appendChild(textElement);
|
|
12039
|
-
markerContainer.appendChild(iconElement);
|
|
12040
|
-
} else {
|
|
12041
|
-
markerContainer.appendChild(iconElement);
|
|
12042
|
-
if (textElement) markerContainer.appendChild(textElement);
|
|
12043
|
-
}
|
|
12044
|
-
return markerContainer;
|
|
12045
|
+
markerContainer.appendChild(iconElement);
|
|
12046
|
+
return this.setAndCreateText(marker, markerContainer);
|
|
12045
12047
|
}
|
|
12046
12048
|
|
|
12047
12049
|
/**
|
|
12048
|
-
*
|
|
12050
|
+
* Appends the marker's text label (if any) to the container, positioned
|
|
12051
|
+
* around whichever element (icon or custom `element`) is already there.
|
|
12049
12052
|
*
|
|
12050
12053
|
* @param markerConfig - Configuration object containing text properties
|
|
12051
|
-
* @param container - Container element
|
|
12052
|
-
* @
|
|
12053
|
-
* @param iconWidth - Width of the icon for positioning calculations
|
|
12054
|
-
* @returns Container element with properly positioned text
|
|
12054
|
+
* @param container - Container element to append the label to
|
|
12055
|
+
* @returns The same container, with the label appended when text is present
|
|
12055
12056
|
*/
|
|
12056
12057
|
}, {
|
|
12057
12058
|
key: "setAndCreateText",
|
|
12058
|
-
value: function setAndCreateText(markerConfig, container
|
|
12059
|
+
value: function setAndCreateText(markerConfig, container) {
|
|
12059
12060
|
if (markerConfig.text) {
|
|
12060
12061
|
var textElement = typeof markerConfig.text === "string" ? this.createTextElement(markerConfig.text, markerConfig.textProperties) : markerConfig.text;
|
|
12061
|
-
var textContainer = this.createTextContainer(textElement, markerConfig.textPosition);
|
|
12062
|
+
var textContainer = this.createTextContainer(textElement, markerConfig.textPosition, markerConfig.maxLabelWidthPx);
|
|
12062
12063
|
container.appendChild(textContainer);
|
|
12063
12064
|
}
|
|
12064
12065
|
return container;
|
|
@@ -12094,43 +12095,75 @@ var MarkerUtils = /*#__PURE__*/function () {
|
|
|
12094
12095
|
}
|
|
12095
12096
|
|
|
12096
12097
|
/**
|
|
12097
|
-
* Creates a text container
|
|
12098
|
-
*
|
|
12098
|
+
* Creates a text container, absolutely positioned around the marker's icon
|
|
12099
|
+
* via CSS (see `.text-container` in styles.css), so the label never affects
|
|
12100
|
+
* the container's own box.
|
|
12099
12101
|
*
|
|
12100
12102
|
* @param textElement - The text element to contain
|
|
12101
12103
|
* @param textPosition - Desired position relative to the icon
|
|
12104
|
+
* @param maxLabelWidthPx - Maximum label width in pixels before truncation
|
|
12102
12105
|
* @returns Container with text positioned using CSS classes
|
|
12103
12106
|
*/
|
|
12104
12107
|
}, {
|
|
12105
12108
|
key: "createTextContainer",
|
|
12106
|
-
value: function createTextContainer(textElement, textPosition) {
|
|
12109
|
+
value: function createTextContainer(textElement, textPosition, maxLabelWidthPx) {
|
|
12107
12110
|
var textContainer = document.createElement("div");
|
|
12108
12111
|
|
|
12109
12112
|
// Apply base class
|
|
12110
12113
|
textContainer.className = "text-container";
|
|
12111
|
-
|
|
12112
|
-
|
|
12113
|
-
switch (textPosition) {
|
|
12114
|
-
case TextPosition.top:
|
|
12115
|
-
textContainer.classList.add("top");
|
|
12116
|
-
break;
|
|
12117
|
-
case TextPosition.bottom:
|
|
12118
|
-
textContainer.classList.add("bottom");
|
|
12119
|
-
break;
|
|
12120
|
-
case TextPosition.left:
|
|
12121
|
-
textContainer.classList.add("left");
|
|
12122
|
-
break;
|
|
12123
|
-
default:
|
|
12124
|
-
// right
|
|
12125
|
-
textContainer.classList.add("right");
|
|
12126
|
-
break;
|
|
12127
|
-
}
|
|
12114
|
+
textContainer.style.maxWidth = "".concat(maxLabelWidthPx !== null && maxLabelWidthPx !== void 0 ? maxLabelWidthPx : DEFAULT_MAX_LABEL_WIDTH_PX, "px");
|
|
12115
|
+
this.setTextPositionClass(textContainer, this.resolveTextPosition(textPosition));
|
|
12128
12116
|
textElement.style.display = "block";
|
|
12129
12117
|
textElement.style.margin = "0";
|
|
12130
12118
|
textContainer.appendChild(textElement);
|
|
12131
12119
|
return textContainer;
|
|
12132
12120
|
}
|
|
12133
12121
|
|
|
12122
|
+
/**
|
|
12123
|
+
* Resolves an optional {@link TextPosition} to its default (`right`), the
|
|
12124
|
+
* same default `createTextContainer` has always applied.
|
|
12125
|
+
*/
|
|
12126
|
+
}, {
|
|
12127
|
+
key: "resolveTextPosition",
|
|
12128
|
+
value: function resolveTextPosition(textPosition) {
|
|
12129
|
+
return textPosition !== null && textPosition !== void 0 ? textPosition : TextPosition.right;
|
|
12130
|
+
}
|
|
12131
|
+
|
|
12132
|
+
/**
|
|
12133
|
+
* Swaps a text container's position class, keeping exactly one of
|
|
12134
|
+
* `top|bottom|left|right` applied at a time.
|
|
12135
|
+
*/
|
|
12136
|
+
}, {
|
|
12137
|
+
key: "setTextPositionClass",
|
|
12138
|
+
value: function setTextPositionClass(textContainer, position) {
|
|
12139
|
+
textContainer.classList.remove("top", "bottom", "left", "right");
|
|
12140
|
+
textContainer.classList.add(TextPosition[position]);
|
|
12141
|
+
}
|
|
12142
|
+
|
|
12143
|
+
/**
|
|
12144
|
+
* Repositions (or hides) a marker's already-rendered text label at
|
|
12145
|
+
* runtime, without rebuilding any DOM. Used both by automatic collision
|
|
12146
|
+
* avoidance and by anything else that needs to move a label after
|
|
12147
|
+
* creation.
|
|
12148
|
+
*
|
|
12149
|
+
* @param textContainer - The `.text-container` element to reposition
|
|
12150
|
+
* @param position - Side of the icon the label should render on
|
|
12151
|
+
* @param hidden - Whether the label should be hidden (kept measurable via
|
|
12152
|
+
* `visibility`, never removed via `display`, so it can be measured again
|
|
12153
|
+
* to decide whether it fits once something else changes)
|
|
12154
|
+
*
|
|
12155
|
+
* @example
|
|
12156
|
+
* ```typescript
|
|
12157
|
+
* MarkerUtils.applyTextPosition(textEl, TextPosition.left, false);
|
|
12158
|
+
* ```
|
|
12159
|
+
*/
|
|
12160
|
+
}, {
|
|
12161
|
+
key: "applyTextPosition",
|
|
12162
|
+
value: function applyTextPosition(textContainer, position, hidden) {
|
|
12163
|
+
this.setTextPositionClass(textContainer, position);
|
|
12164
|
+
textContainer.style.visibility = hidden ? "hidden" : "";
|
|
12165
|
+
}
|
|
12166
|
+
|
|
12134
12167
|
/**
|
|
12135
12168
|
* Creates and returns an icon element for the marker, using the image URL
|
|
12136
12169
|
* specified in the `MarkerConfig` object.
|
|
@@ -12150,8 +12183,8 @@ var MarkerUtils = /*#__PURE__*/function () {
|
|
|
12150
12183
|
var _marker$iconPropertie5, _marker$iconPropertie6, _marker$iconPropertie7, _marker$iconPropertie8;
|
|
12151
12184
|
var image = document.createElement("img");
|
|
12152
12185
|
image.src = typeof marker.icon == "string" ? marker.icon : "";
|
|
12153
|
-
image.width = (_marker$iconPropertie5 = (_marker$iconPropertie6 = marker.iconProperties) === null || _marker$iconPropertie6 === void 0 ? void 0 : _marker$iconPropertie6.width) !== null && _marker$iconPropertie5 !== void 0 ? _marker$iconPropertie5 :
|
|
12154
|
-
image.height = (_marker$iconPropertie7 = (_marker$iconPropertie8 = marker.iconProperties) === null || _marker$iconPropertie8 === void 0 ? void 0 : _marker$iconPropertie8.height) !== null && _marker$iconPropertie7 !== void 0 ? _marker$iconPropertie7 :
|
|
12186
|
+
image.width = (_marker$iconPropertie5 = (_marker$iconPropertie6 = marker.iconProperties) === null || _marker$iconPropertie6 === void 0 ? void 0 : _marker$iconPropertie6.width) !== null && _marker$iconPropertie5 !== void 0 ? _marker$iconPropertie5 : DEFAULT_ICON_SIZE_PX;
|
|
12187
|
+
image.height = (_marker$iconPropertie7 = (_marker$iconPropertie8 = marker.iconProperties) === null || _marker$iconPropertie8 === void 0 ? void 0 : _marker$iconPropertie8.height) !== null && _marker$iconPropertie7 !== void 0 ? _marker$iconPropertie7 : DEFAULT_ICON_SIZE_PX;
|
|
12155
12188
|
image.style.objectFit = "contain";
|
|
12156
12189
|
image.style.filter = "drop-shadow(0px 4px 4px rgba(0, 0, 0, 0.25))";
|
|
12157
12190
|
return image;
|
|
@@ -12190,6 +12223,7 @@ var MarkerUtils = /*#__PURE__*/function () {
|
|
|
12190
12223
|
}
|
|
12191
12224
|
}]);
|
|
12192
12225
|
}();
|
|
12226
|
+
|
|
12193
12227
|
/**
|
|
12194
12228
|
* Custom implementation of a MapLibre Marker with additional functionality.
|
|
12195
12229
|
* Extends the base MapLibre Marker class with MapVX-specific features.
|
|
@@ -12220,6 +12254,56 @@ var MarkerAttribute = /*#__PURE__*/function (_Marker) {
|
|
|
12220
12254
|
* Used for indoor navigation and floor-specific marker management.
|
|
12221
12255
|
*/
|
|
12222
12256
|
|
|
12257
|
+
/**
|
|
12258
|
+
* Resolved icon dimensions (defaults to {@link DEFAULT_ICON_SIZE_PX} square
|
|
12259
|
+
* when unspecified), matching whatever `MarkerUtils.createMarkerElement`
|
|
12260
|
+
* rendered. Used by automatic label collision avoidance to compute the
|
|
12261
|
+
* icon's on-screen rect without a DOM measurement — except when
|
|
12262
|
+
* {@link measureIconFromDom} is set.
|
|
12263
|
+
* @internal
|
|
12264
|
+
*/
|
|
12265
|
+
|
|
12266
|
+
/**
|
|
12267
|
+
* The `PositionAnchor` this marker was created with, needed by automatic
|
|
12268
|
+
* label collision avoidance to translate a screen point into the icon's
|
|
12269
|
+
* on-screen rect the same way MapLibre itself does.
|
|
12270
|
+
* @internal
|
|
12271
|
+
*/
|
|
12272
|
+
|
|
12273
|
+
/**
|
|
12274
|
+
* The marker's preferred text position, used as the first candidate by
|
|
12275
|
+
* automatic label collision avoidance before it tries the other sides.
|
|
12276
|
+
* @internal
|
|
12277
|
+
*/
|
|
12278
|
+
|
|
12279
|
+
/**
|
|
12280
|
+
* Priority used to resolve label collisions; see
|
|
12281
|
+
* {@link MarkerConfig.labelPriority}.
|
|
12282
|
+
* @internal
|
|
12283
|
+
*/
|
|
12284
|
+
|
|
12285
|
+
/**
|
|
12286
|
+
* Cached reference to this marker's `.text-container` element, if it has
|
|
12287
|
+
* a text label. Avoids querying the DOM on every layout pass.
|
|
12288
|
+
* @internal
|
|
12289
|
+
*/
|
|
12290
|
+
|
|
12291
|
+
/**
|
|
12292
|
+
* True when the marker renders a caller-supplied `element` and no
|
|
12293
|
+
* `iconProperties` declared its footprint. In that case {@link iconSize}
|
|
12294
|
+
* is only a fallback and automatic label collision avoidance measures the
|
|
12295
|
+
* marker element's real box from the DOM instead.
|
|
12296
|
+
* @internal
|
|
12297
|
+
*/
|
|
12298
|
+
|
|
12299
|
+
/**
|
|
12300
|
+
* The config this marker currently renders from. {@link updateIcon} merges
|
|
12301
|
+
* its (usually partial) config on top of this one, so an update that omits
|
|
12302
|
+
* `iconProperties`, `textPosition` or `labelPriority` keeps whatever the
|
|
12303
|
+
* marker already had instead of silently snapping back to the SDK defaults
|
|
12304
|
+
* — both in the DOM it rebuilds and in the layout state derived from it.
|
|
12305
|
+
*/
|
|
12306
|
+
|
|
12223
12307
|
/**
|
|
12224
12308
|
* Constructs a new `MarkerAttribute` object with the specified properties.
|
|
12225
12309
|
*
|
|
@@ -12236,7 +12320,7 @@ var MarkerAttribute = /*#__PURE__*/function (_Marker) {
|
|
|
12236
12320
|
* ```
|
|
12237
12321
|
*/
|
|
12238
12322
|
function MarkerAttribute(markerConfig) {
|
|
12239
|
-
var _markerConfig$anchor, _markerConfig$rotatio, _markerConfig$id, _markerConfig$floorId;
|
|
12323
|
+
var _markerConfig$anchor, _markerConfig$rotatio, _markerConfig$id, _markerConfig$floorId, _markerConfig$anchor2;
|
|
12240
12324
|
var _this;
|
|
12241
12325
|
marker_classCallCheck(this, MarkerAttribute);
|
|
12242
12326
|
_this = _callSuper(this, MarkerAttribute, [{
|
|
@@ -12254,22 +12338,78 @@ var MarkerAttribute = /*#__PURE__*/function (_Marker) {
|
|
|
12254
12338
|
_this.id = (_markerConfig$id = markerConfig.id) !== null && _markerConfig$id !== void 0 ? _markerConfig$id : generateHexadecimalKey();
|
|
12255
12339
|
_this.coordinate = markerConfig.coordinate;
|
|
12256
12340
|
_this.floorId = (_markerConfig$floorId = markerConfig.floorId) !== null && _markerConfig$floorId !== void 0 ? _markerConfig$floorId : "";
|
|
12341
|
+
// MapLibre resolves the anchor once, in the `super()` call above, and
|
|
12342
|
+
// offers no way to change it afterwards — so this mirror is set here and
|
|
12343
|
+
// never touched by `updateIcon`.
|
|
12344
|
+
_this.anchorType = (_markerConfig$anchor2 = markerConfig.anchor) !== null && _markerConfig$anchor2 !== void 0 ? _markerConfig$anchor2 : "center";
|
|
12345
|
+
_this.currentConfig = markerConfig;
|
|
12346
|
+
_this.applyLayoutState(markerConfig);
|
|
12257
12347
|
return _this;
|
|
12258
12348
|
}
|
|
12259
12349
|
|
|
12260
12350
|
/**
|
|
12261
|
-
*
|
|
12262
|
-
*
|
|
12263
|
-
*
|
|
12264
|
-
*
|
|
12265
|
-
* @
|
|
12266
|
-
*
|
|
12267
|
-
* const marker = new MarkerAttribute(markerConfig);
|
|
12268
|
-
* marker.addToMap(mapInstance);
|
|
12269
|
-
* ```
|
|
12351
|
+
* Derives the state automatic label collision avoidance reads (icon box,
|
|
12352
|
+
* preferred label side, priority, label element) from a fully-resolved
|
|
12353
|
+
* config. It is what assigns the fields declared with `!` above — the
|
|
12354
|
+
* constructor always calls it, but TypeScript can't see through the
|
|
12355
|
+
* indirection. Shared by the constructor and {@link updateIcon} so the two can
|
|
12356
|
+
* never drift apart.
|
|
12270
12357
|
*/
|
|
12271
12358
|
_inherits(MarkerAttribute, _Marker);
|
|
12272
12359
|
return marker_createClass(MarkerAttribute, [{
|
|
12360
|
+
key: "applyLayoutState",
|
|
12361
|
+
value: function applyLayoutState(config) {
|
|
12362
|
+
var _config$iconPropertie, _config$iconPropertie2, _config$iconPropertie3, _config$iconPropertie4, _config$labelPriority;
|
|
12363
|
+
this.iconSize = {
|
|
12364
|
+
width: (_config$iconPropertie = (_config$iconPropertie2 = config.iconProperties) === null || _config$iconPropertie2 === void 0 ? void 0 : _config$iconPropertie2.width) !== null && _config$iconPropertie !== void 0 ? _config$iconPropertie : DEFAULT_ICON_SIZE_PX,
|
|
12365
|
+
height: (_config$iconPropertie3 = (_config$iconPropertie4 = config.iconProperties) === null || _config$iconPropertie4 === void 0 ? void 0 : _config$iconPropertie4.height) !== null && _config$iconPropertie3 !== void 0 ? _config$iconPropertie3 : DEFAULT_ICON_SIZE_PX
|
|
12366
|
+
};
|
|
12367
|
+
this.preferredTextPosition = MarkerUtils.resolveTextPosition(config.textPosition);
|
|
12368
|
+
this.labelPriority = (_config$labelPriority = config.labelPriority) !== null && _config$labelPriority !== void 0 ? _config$labelPriority : 0;
|
|
12369
|
+
this.measureIconFromDom = config.element != null && config.iconProperties == null;
|
|
12370
|
+
this.textContainerEl = this.findTextContainerEl();
|
|
12371
|
+
}
|
|
12372
|
+
|
|
12373
|
+
/**
|
|
12374
|
+
* Merges an update on top of the marker's current config, so a partial
|
|
12375
|
+
* update such as `{ id, coordinate, icon }` keeps the marker's existing
|
|
12376
|
+
* icon dimensions, label side and priority.
|
|
12377
|
+
*
|
|
12378
|
+
* `element` is deliberately *not* carried forward: it and `icon` are
|
|
12379
|
+
* mutually exclusive rendering paths, and `updateIcon` has always chosen
|
|
12380
|
+
* the path named by the update itself.
|
|
12381
|
+
*/
|
|
12382
|
+
}, {
|
|
12383
|
+
key: "mergeConfig",
|
|
12384
|
+
value: function mergeConfig(update) {
|
|
12385
|
+
return marker_objectSpread(marker_objectSpread(marker_objectSpread({}, this.currentConfig), update), {}, {
|
|
12386
|
+
element: update.element
|
|
12387
|
+
});
|
|
12388
|
+
}
|
|
12389
|
+
|
|
12390
|
+
/**
|
|
12391
|
+
* Finds this marker's `.text-container` child element, if it has one.
|
|
12392
|
+
*/
|
|
12393
|
+
}, {
|
|
12394
|
+
key: "findTextContainerEl",
|
|
12395
|
+
value: function findTextContainerEl() {
|
|
12396
|
+
return Array.from(this._element.children).find(function (child) {
|
|
12397
|
+
return child instanceof HTMLElement && child.classList.contains("text-container");
|
|
12398
|
+
});
|
|
12399
|
+
}
|
|
12400
|
+
|
|
12401
|
+
/**
|
|
12402
|
+
* Adds the marker attribute to the specified map.
|
|
12403
|
+
*
|
|
12404
|
+
* @param map - The map instance where the marker attribute will be added
|
|
12405
|
+
*
|
|
12406
|
+
* @example
|
|
12407
|
+
* ```typescript
|
|
12408
|
+
* const marker = new MarkerAttribute(markerConfig);
|
|
12409
|
+
* marker.addToMap(mapInstance);
|
|
12410
|
+
* ```
|
|
12411
|
+
*/
|
|
12412
|
+
}, {
|
|
12273
12413
|
key: "addToMap",
|
|
12274
12414
|
value: function addToMap(map) {
|
|
12275
12415
|
if (!map) return;
|
|
@@ -12279,6 +12419,11 @@ var MarkerAttribute = /*#__PURE__*/function (_Marker) {
|
|
|
12279
12419
|
/**
|
|
12280
12420
|
* Updates the icon of the marker attribute based on the specified marker configuration.
|
|
12281
12421
|
*
|
|
12422
|
+
* The config is merged on top of the one the marker currently renders
|
|
12423
|
+
* from, so a partial update keeps every property it omits — passing only
|
|
12424
|
+
* `{ icon }` no longer resets the marker's icon dimensions, preferred
|
|
12425
|
+
* label side or label priority to their defaults.
|
|
12426
|
+
*
|
|
12282
12427
|
* @param marker - `MarkerConfig` object containing the new marker configuration
|
|
12283
12428
|
*
|
|
12284
12429
|
* @example
|
|
@@ -12292,12 +12437,13 @@ var MarkerAttribute = /*#__PURE__*/function (_Marker) {
|
|
|
12292
12437
|
}, {
|
|
12293
12438
|
key: "updateIcon",
|
|
12294
12439
|
value: function updateIcon(marker) {
|
|
12295
|
-
var
|
|
12296
|
-
|
|
12440
|
+
var _config$rotationAlign;
|
|
12441
|
+
var config = this.mergeConfig(marker);
|
|
12442
|
+
if (config.element) {
|
|
12297
12443
|
this._element.innerHTML = "";
|
|
12298
|
-
this._element.appendChild(
|
|
12444
|
+
this._element.appendChild(config.element);
|
|
12299
12445
|
} else {
|
|
12300
|
-
var markerElement = MarkerUtils.createMarkerElement(
|
|
12446
|
+
var markerElement = MarkerUtils.createMarkerElement(config);
|
|
12301
12447
|
var oldMarkerContent = this._element.querySelector("div");
|
|
12302
12448
|
var newMarkerContent = markerElement.querySelector("div");
|
|
12303
12449
|
if (newMarkerContent) {
|
|
@@ -12305,11 +12451,13 @@ var MarkerAttribute = /*#__PURE__*/function (_Marker) {
|
|
|
12305
12451
|
oldMarkerContent === null || oldMarkerContent === void 0 || (_oldMarkerContent$par = oldMarkerContent.parentElement) === null || _oldMarkerContent$par === void 0 || _oldMarkerContent$par.replaceChild(newMarkerContent, oldMarkerContent);
|
|
12306
12452
|
}
|
|
12307
12453
|
}
|
|
12308
|
-
this.setRotationAlignment((
|
|
12454
|
+
this.setRotationAlignment((_config$rotationAlign = config.rotationAlignment) !== null && _config$rotationAlign !== void 0 ? _config$rotationAlign : "viewport");
|
|
12309
12455
|
this.setPitchAlignment("viewport");
|
|
12310
|
-
if (typeof
|
|
12311
|
-
this.setRotation(
|
|
12456
|
+
if (typeof config.rotation === "number") {
|
|
12457
|
+
this.setRotation(config.rotation);
|
|
12312
12458
|
}
|
|
12459
|
+
this.currentConfig = config;
|
|
12460
|
+
this.applyLayoutState(config);
|
|
12313
12461
|
}
|
|
12314
12462
|
|
|
12315
12463
|
/**
|
|
@@ -12386,6 +12534,452 @@ var MarkerAttribute = /*#__PURE__*/function (_Marker) {
|
|
|
12386
12534
|
}
|
|
12387
12535
|
}]);
|
|
12388
12536
|
}(maplibre_gl.Marker);
|
|
12537
|
+
;// ./src/controllers/markerLayoutController.ts
|
|
12538
|
+
function markerLayoutController_typeof(o) { "@babel/helpers - typeof"; return markerLayoutController_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, markerLayoutController_typeof(o); }
|
|
12539
|
+
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || markerLayoutController_unsupportedIterableToArray(r) || _nonIterableSpread(); }
|
|
12540
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
12541
|
+
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
|
|
12542
|
+
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return markerLayoutController_arrayLikeToArray(r); }
|
|
12543
|
+
function markerLayoutController_createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = markerLayoutController_unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
12544
|
+
function markerLayoutController_unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return markerLayoutController_arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? markerLayoutController_arrayLikeToArray(r, a) : void 0; } }
|
|
12545
|
+
function markerLayoutController_arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
12546
|
+
function markerLayoutController_classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
|
|
12547
|
+
function markerLayoutController_defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, markerLayoutController_toPropertyKey(o.key), o); } }
|
|
12548
|
+
function markerLayoutController_createClass(e, r, t) { return r && markerLayoutController_defineProperties(e.prototype, r), t && markerLayoutController_defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
|
|
12549
|
+
function markerLayoutController_defineProperty(e, r, t) { return (r = markerLayoutController_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
12550
|
+
function markerLayoutController_toPropertyKey(t) { var i = markerLayoutController_toPrimitive(t, "string"); return "symbol" == markerLayoutController_typeof(i) ? i : i + ""; }
|
|
12551
|
+
function markerLayoutController_toPrimitive(t, r) { if ("object" != markerLayoutController_typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != markerLayoutController_typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
12552
|
+
|
|
12553
|
+
|
|
12554
|
+
/** Axis-aligned box in screen (CSS pixel) space. */
|
|
12555
|
+
|
|
12556
|
+
/**
|
|
12557
|
+
* Fraction of the icon's own box, along each axis, that MapLibre's Marker
|
|
12558
|
+
* anchor math (`translate(-x%, -y%)`) aligns to the geodetic point. Mirrors
|
|
12559
|
+
* MapLibre's own `anchorTranslate` table so the collision math agrees with
|
|
12560
|
+
* what's actually on screen.
|
|
12561
|
+
*/
|
|
12562
|
+
var ANCHOR_FRACTIONS = {
|
|
12563
|
+
center: {
|
|
12564
|
+
fx: 0.5,
|
|
12565
|
+
fy: 0.5
|
|
12566
|
+
},
|
|
12567
|
+
top: {
|
|
12568
|
+
fx: 0.5,
|
|
12569
|
+
fy: 0
|
|
12570
|
+
},
|
|
12571
|
+
bottom: {
|
|
12572
|
+
fx: 0.5,
|
|
12573
|
+
fy: 1
|
|
12574
|
+
},
|
|
12575
|
+
left: {
|
|
12576
|
+
fx: 0,
|
|
12577
|
+
fy: 0.5
|
|
12578
|
+
},
|
|
12579
|
+
right: {
|
|
12580
|
+
fx: 1,
|
|
12581
|
+
fy: 0.5
|
|
12582
|
+
},
|
|
12583
|
+
"top-left": {
|
|
12584
|
+
fx: 0,
|
|
12585
|
+
fy: 0
|
|
12586
|
+
},
|
|
12587
|
+
"top-right": {
|
|
12588
|
+
fx: 1,
|
|
12589
|
+
fy: 0
|
|
12590
|
+
},
|
|
12591
|
+
"bottom-left": {
|
|
12592
|
+
fx: 0,
|
|
12593
|
+
fy: 1
|
|
12594
|
+
},
|
|
12595
|
+
"bottom-right": {
|
|
12596
|
+
fx: 1,
|
|
12597
|
+
fy: 1
|
|
12598
|
+
}
|
|
12599
|
+
};
|
|
12600
|
+
|
|
12601
|
+
/** Candidate order tried when a marker's preferred side is unavailable. */
|
|
12602
|
+
var FALLBACK_ORDER = [TextPosition.right, TextPosition.top, TextPosition.left, TextPosition.bottom];
|
|
12603
|
+
|
|
12604
|
+
/** Builds the icon's on-screen rect from its projected point, size and anchor. */
|
|
12605
|
+
function computeIconRect(screen, iconSize, anchor) {
|
|
12606
|
+
var _ANCHOR_FRACTIONS$anc;
|
|
12607
|
+
var _ref = (_ANCHOR_FRACTIONS$anc = ANCHOR_FRACTIONS[anchor]) !== null && _ANCHOR_FRACTIONS$anc !== void 0 ? _ANCHOR_FRACTIONS$anc : ANCHOR_FRACTIONS.center,
|
|
12608
|
+
fx = _ref.fx,
|
|
12609
|
+
fy = _ref.fy;
|
|
12610
|
+
return {
|
|
12611
|
+
left: screen.x - fx * iconSize.width,
|
|
12612
|
+
top: screen.y - fy * iconSize.height,
|
|
12613
|
+
width: iconSize.width,
|
|
12614
|
+
height: iconSize.height
|
|
12615
|
+
};
|
|
12616
|
+
}
|
|
12617
|
+
|
|
12618
|
+
/**
|
|
12619
|
+
* Builds a candidate label rect for one side of an icon. Mirrors the CSS in
|
|
12620
|
+
* `styles.css` (`.text-container.right/left/top/bottom`) exactly, so a
|
|
12621
|
+
* position the algorithm picks as collision-free renders collision-free.
|
|
12622
|
+
*/
|
|
12623
|
+
function computeCandidateRect(iconRect, labelSize, position, gapPx, verticalGapPx) {
|
|
12624
|
+
switch (position) {
|
|
12625
|
+
case TextPosition.left:
|
|
12626
|
+
return {
|
|
12627
|
+
left: iconRect.left - gapPx - labelSize.width,
|
|
12628
|
+
top: iconRect.top + iconRect.height / 2 - labelSize.height / 2,
|
|
12629
|
+
width: labelSize.width,
|
|
12630
|
+
height: labelSize.height
|
|
12631
|
+
};
|
|
12632
|
+
case TextPosition.top:
|
|
12633
|
+
return {
|
|
12634
|
+
left: iconRect.left + iconRect.width / 2 - labelSize.width / 2,
|
|
12635
|
+
top: iconRect.top - verticalGapPx - labelSize.height,
|
|
12636
|
+
width: labelSize.width,
|
|
12637
|
+
height: labelSize.height
|
|
12638
|
+
};
|
|
12639
|
+
case TextPosition.bottom:
|
|
12640
|
+
return {
|
|
12641
|
+
left: iconRect.left + iconRect.width / 2 - labelSize.width / 2,
|
|
12642
|
+
top: iconRect.top + iconRect.height + verticalGapPx,
|
|
12643
|
+
width: labelSize.width,
|
|
12644
|
+
height: labelSize.height
|
|
12645
|
+
};
|
|
12646
|
+
case TextPosition.right:
|
|
12647
|
+
default:
|
|
12648
|
+
return {
|
|
12649
|
+
left: iconRect.left + iconRect.width + gapPx,
|
|
12650
|
+
top: iconRect.top + iconRect.height / 2 - labelSize.height / 2,
|
|
12651
|
+
width: labelSize.width,
|
|
12652
|
+
height: labelSize.height
|
|
12653
|
+
};
|
|
12654
|
+
}
|
|
12655
|
+
}
|
|
12656
|
+
|
|
12657
|
+
/** Expands a rect by `padding` on every side. */
|
|
12658
|
+
function expandRect(rect, padding) {
|
|
12659
|
+
return {
|
|
12660
|
+
left: rect.left - padding,
|
|
12661
|
+
top: rect.top - padding,
|
|
12662
|
+
width: rect.width + 2 * padding,
|
|
12663
|
+
height: rect.height + 2 * padding
|
|
12664
|
+
};
|
|
12665
|
+
}
|
|
12666
|
+
|
|
12667
|
+
/** Standard AABB intersection test. */
|
|
12668
|
+
function rectsIntersect(a, b) {
|
|
12669
|
+
return a.left < b.left + b.width && a.left + a.width > b.left && a.top < b.top + b.height && a.top + a.height > b.top;
|
|
12670
|
+
}
|
|
12671
|
+
|
|
12672
|
+
/**
|
|
12673
|
+
* Automatic collision avoidance for marker text labels: keeps a marker's
|
|
12674
|
+
* icon fixed while moving (or hiding) its label to avoid overlapping
|
|
12675
|
+
* neighboring markers' icons/labels, similar to Google Maps' label
|
|
12676
|
+
* placement. See {@link MarkerLayoutConfig}.
|
|
12677
|
+
*
|
|
12678
|
+
* Not part of the public SDK surface — owned and driven entirely by
|
|
12679
|
+
* {@link InternalMapVXMap}, mirroring `RouteController`.
|
|
12680
|
+
*/
|
|
12681
|
+
var MarkerLayoutController = /*#__PURE__*/function () {
|
|
12682
|
+
function MarkerLayoutController(map, config) {
|
|
12683
|
+
var _this = this;
|
|
12684
|
+
markerLayoutController_classCallCheck(this, MarkerLayoutController);
|
|
12685
|
+
markerLayoutController_defineProperty(this, "labelSizeCache", new WeakMap());
|
|
12686
|
+
markerLayoutController_defineProperty(this, "iconSizeCache", new WeakMap());
|
|
12687
|
+
markerLayoutController_defineProperty(this, "lastAppliedState", new WeakMap());
|
|
12688
|
+
markerLayoutController_defineProperty(this, "attached", false);
|
|
12689
|
+
this.mapvxMap = map;
|
|
12690
|
+
this.config = config;
|
|
12691
|
+
this.boundOnMove = function () {
|
|
12692
|
+
return _this.scheduleRelayout();
|
|
12693
|
+
};
|
|
12694
|
+
}
|
|
12695
|
+
return markerLayoutController_createClass(MarkerLayoutController, [{
|
|
12696
|
+
key: "map",
|
|
12697
|
+
get: function get() {
|
|
12698
|
+
return this.mapvxMap.map;
|
|
12699
|
+
}
|
|
12700
|
+
|
|
12701
|
+
/**
|
|
12702
|
+
* Starts listening for camera movement. Safe to call once the underlying
|
|
12703
|
+
* MapLibre `Map` instance exists; a single `"move"` listener covers pan,
|
|
12704
|
+
* zoom, rotate, pitch and `resize()`.
|
|
12705
|
+
*/
|
|
12706
|
+
}, {
|
|
12707
|
+
key: "attach",
|
|
12708
|
+
value: function attach() {
|
|
12709
|
+
if (this.attached) return;
|
|
12710
|
+
this.attached = true;
|
|
12711
|
+
this.map.on("move", this.boundOnMove);
|
|
12712
|
+
this.remeasureWhenFontsLoad();
|
|
12713
|
+
this.scheduleRelayout();
|
|
12714
|
+
}
|
|
12715
|
+
|
|
12716
|
+
/**
|
|
12717
|
+
* Publishes the configured gaps and label width cap as CSS custom
|
|
12718
|
+
* properties, which `styles.css` reads to offset labels from their icon.
|
|
12719
|
+
* Without this the stylesheet would keep its hardcoded defaults while the
|
|
12720
|
+
* collision math used the configured values, so any custom `gapPx` /
|
|
12721
|
+
* `verticalGapPx` would produce placements this controller believes are
|
|
12722
|
+
* collision-free but that visibly overlap on screen.
|
|
12723
|
+
*
|
|
12724
|
+
* Called with the map's own container, so every marker MapLibre mounts
|
|
12725
|
+
* inside it inherits the values.
|
|
12726
|
+
*/
|
|
12727
|
+
}, {
|
|
12728
|
+
key: "applyLayoutVariables",
|
|
12729
|
+
value: function applyLayoutVariables(container) {
|
|
12730
|
+
container.style.setProperty("--mapvx-label-gap", "".concat(this.config.gapPx, "px"));
|
|
12731
|
+
container.style.setProperty("--mapvx-label-vertical-gap", "".concat(this.config.verticalGapPx, "px"));
|
|
12732
|
+
container.style.setProperty("--mapvx-label-max-width", "".concat(this.config.maxLabelWidthPx, "px"));
|
|
12733
|
+
}
|
|
12734
|
+
|
|
12735
|
+
/**
|
|
12736
|
+
* A label measured before its web font finishes loading is measured in the
|
|
12737
|
+
* fallback font, and that wrong footprint would otherwise be cached for
|
|
12738
|
+
* the marker's lifetime. Drop every measurement once fonts settle.
|
|
12739
|
+
*/
|
|
12740
|
+
}, {
|
|
12741
|
+
key: "remeasureWhenFontsLoad",
|
|
12742
|
+
value: function remeasureWhenFontsLoad() {
|
|
12743
|
+
var _this2 = this;
|
|
12744
|
+
var fonts = document.fonts;
|
|
12745
|
+
if (!fonts) return;
|
|
12746
|
+
fonts.ready.then(function () {
|
|
12747
|
+
if (!_this2.attached) return;
|
|
12748
|
+
_this2.labelSizeCache = new WeakMap();
|
|
12749
|
+
_this2.iconSizeCache = new WeakMap();
|
|
12750
|
+
_this2.scheduleRelayout();
|
|
12751
|
+
})["catch"](function () {
|
|
12752
|
+
// Font loading failing is not a layout error: the measurements
|
|
12753
|
+
// already taken in the fallback font stay in effect.
|
|
12754
|
+
});
|
|
12755
|
+
}
|
|
12756
|
+
|
|
12757
|
+
/** Stops listening and cancels any pending layout pass. */
|
|
12758
|
+
}, {
|
|
12759
|
+
key: "destroy",
|
|
12760
|
+
value: function destroy() {
|
|
12761
|
+
if (this.attached) {
|
|
12762
|
+
this.map.off("move", this.boundOnMove);
|
|
12763
|
+
this.attached = false;
|
|
12764
|
+
}
|
|
12765
|
+
if (this.rafHandle !== undefined) {
|
|
12766
|
+
cancelAnimationFrame(this.rafHandle);
|
|
12767
|
+
this.rafHandle = undefined;
|
|
12768
|
+
}
|
|
12769
|
+
}
|
|
12770
|
+
|
|
12771
|
+
/**
|
|
12772
|
+
* Drops everything cached for a marker, e.g. after its text/content
|
|
12773
|
+
* changed.
|
|
12774
|
+
*
|
|
12775
|
+
* The last applied decision has to go too: rebuilding a marker's DOM
|
|
12776
|
+
* replaces its `.text-container` with a fresh one carrying the preferred
|
|
12777
|
+
* side and no `visibility`, so a decision remembered from the old element
|
|
12778
|
+
* would make {@link applyDecisions} short-circuit and leave the new label
|
|
12779
|
+
* on the wrong side — or visible when it should be hidden.
|
|
12780
|
+
*/
|
|
12781
|
+
}, {
|
|
12782
|
+
key: "invalidateMarker",
|
|
12783
|
+
value: function invalidateMarker(marker) {
|
|
12784
|
+
this.labelSizeCache["delete"](marker);
|
|
12785
|
+
this.iconSizeCache["delete"](marker);
|
|
12786
|
+
this.lastAppliedState["delete"](marker);
|
|
12787
|
+
}
|
|
12788
|
+
|
|
12789
|
+
/** Coalesces repeated calls into a single layout pass per animation frame. */
|
|
12790
|
+
}, {
|
|
12791
|
+
key: "scheduleRelayout",
|
|
12792
|
+
value: function scheduleRelayout() {
|
|
12793
|
+
var _this3 = this;
|
|
12794
|
+
if (!this.config.enabled || this.rafHandle !== undefined) return;
|
|
12795
|
+
this.rafHandle = requestAnimationFrame(function () {
|
|
12796
|
+
_this3.rafHandle = undefined;
|
|
12797
|
+
_this3.performLayout();
|
|
12798
|
+
});
|
|
12799
|
+
}
|
|
12800
|
+
}, {
|
|
12801
|
+
key: "performLayout",
|
|
12802
|
+
value: function performLayout() {
|
|
12803
|
+
// Guards against a relayout firing before the underlying MapLibre `map`
|
|
12804
|
+
// exists (e.g. a marker added before the "load" event) — `attach()`
|
|
12805
|
+
// schedules its own initial pass once it's safe to touch `this.map`.
|
|
12806
|
+
if (!this.attached) return;
|
|
12807
|
+
var markers = this.mapvxMap.getMarkers();
|
|
12808
|
+
if (markers.length === 0) return;
|
|
12809
|
+
var container = this.map.getContainer();
|
|
12810
|
+
var viewportWidth = container.clientWidth;
|
|
12811
|
+
var viewportHeight = container.clientHeight;
|
|
12812
|
+
var cullMargin = this.config.maxLabelWidthPx + Math.max(this.config.gapPx, this.config.verticalGapPx);
|
|
12813
|
+
var entries = this.readMarkers(markers, viewportWidth, viewportHeight, cullMargin);
|
|
12814
|
+
var decisions = this.decidePlacements(entries);
|
|
12815
|
+
this.applyDecisions(decisions);
|
|
12816
|
+
}
|
|
12817
|
+
|
|
12818
|
+
/** Read phase: project + measure, no writes. Culls markers fully outside the viewport. */
|
|
12819
|
+
}, {
|
|
12820
|
+
key: "readMarkers",
|
|
12821
|
+
value: function readMarkers(markers, viewportWidth, viewportHeight, cullMargin) {
|
|
12822
|
+
var entries = [];
|
|
12823
|
+
var _iterator = markerLayoutController_createForOfIteratorHelper(markers),
|
|
12824
|
+
_step;
|
|
12825
|
+
try {
|
|
12826
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
12827
|
+
var marker = _step.value;
|
|
12828
|
+
if (!marker.getElement().isConnected) continue;
|
|
12829
|
+
var screen = this.map.project(marker.getLngLat());
|
|
12830
|
+
var iconRect = computeIconRect(screen, this.resolveIconSize(marker), marker.anchorType);
|
|
12831
|
+
var outOfViewport = iconRect.left + iconRect.width < -cullMargin || iconRect.left > viewportWidth + cullMargin || iconRect.top + iconRect.height < -cullMargin || iconRect.top > viewportHeight + cullMargin;
|
|
12832
|
+
if (outOfViewport) continue;
|
|
12833
|
+
entries.push({
|
|
12834
|
+
marker: marker,
|
|
12835
|
+
iconRect: iconRect,
|
|
12836
|
+
labelSize: this.resolveLabelSize(marker)
|
|
12837
|
+
});
|
|
12838
|
+
}
|
|
12839
|
+
} catch (err) {
|
|
12840
|
+
_iterator.e(err);
|
|
12841
|
+
} finally {
|
|
12842
|
+
_iterator.f();
|
|
12843
|
+
}
|
|
12844
|
+
return entries;
|
|
12845
|
+
}
|
|
12846
|
+
}, {
|
|
12847
|
+
key: "resolveLabelSize",
|
|
12848
|
+
value: function resolveLabelSize(marker) {
|
|
12849
|
+
var textEl = marker.textContainerEl;
|
|
12850
|
+
if (!textEl) return undefined;
|
|
12851
|
+
return this.measureCached(this.labelSizeCache, marker, textEl);
|
|
12852
|
+
}
|
|
12853
|
+
|
|
12854
|
+
/**
|
|
12855
|
+
* The icon's box. Markers built from a caller-supplied `element` with no
|
|
12856
|
+
* declared `iconProperties` are measured from the DOM, since their real
|
|
12857
|
+
* size is whatever that element renders at; everyone else's box is exactly
|
|
12858
|
+
* what `MarkerUtils.createMarkerElement` pinned it to.
|
|
12859
|
+
*/
|
|
12860
|
+
}, {
|
|
12861
|
+
key: "resolveIconSize",
|
|
12862
|
+
value: function resolveIconSize(marker) {
|
|
12863
|
+
var _this$measureCached;
|
|
12864
|
+
if (!marker.measureIconFromDom) return marker.iconSize;
|
|
12865
|
+
return (_this$measureCached = this.measureCached(this.iconSizeCache, marker, marker.getElement())) !== null && _this$measureCached !== void 0 ? _this$measureCached : marker.iconSize;
|
|
12866
|
+
}
|
|
12867
|
+
|
|
12868
|
+
/**
|
|
12869
|
+
* Measures an element once and remembers it. A zero measurement is
|
|
12870
|
+
* returned but never cached: it means the element isn't laid out yet (a
|
|
12871
|
+
* `display: none` ancestor, a first pass before the web font loads), and
|
|
12872
|
+
* caching it would freeze that marker's footprint at nothing for the rest
|
|
12873
|
+
* of its life.
|
|
12874
|
+
*/
|
|
12875
|
+
}, {
|
|
12876
|
+
key: "measureCached",
|
|
12877
|
+
value: function measureCached(cache, marker, element) {
|
|
12878
|
+
var cached = cache.get(marker);
|
|
12879
|
+
if (cached) return cached;
|
|
12880
|
+
var measured = {
|
|
12881
|
+
width: element.offsetWidth,
|
|
12882
|
+
height: element.offsetHeight
|
|
12883
|
+
};
|
|
12884
|
+
if (measured.width <= 0 || measured.height <= 0) return undefined;
|
|
12885
|
+
cache.set(marker, measured);
|
|
12886
|
+
return measured;
|
|
12887
|
+
}
|
|
12888
|
+
|
|
12889
|
+
/** Compute phase: pure, no DOM access. Icons always block; labels negotiate a side or hide. */
|
|
12890
|
+
}, {
|
|
12891
|
+
key: "decidePlacements",
|
|
12892
|
+
value: function decidePlacements(entries) {
|
|
12893
|
+
var _this4 = this;
|
|
12894
|
+
var placedLabels = [];
|
|
12895
|
+
var withLabel = entries.filter(hasLabelSize);
|
|
12896
|
+
// Stable sort (spec-guaranteed): equal priority keeps insertion order.
|
|
12897
|
+
withLabel.sort(function (a, b) {
|
|
12898
|
+
return b.marker.labelPriority - a.marker.labelPriority;
|
|
12899
|
+
});
|
|
12900
|
+
var decisions = new Map();
|
|
12901
|
+
var _iterator2 = markerLayoutController_createForOfIteratorHelper(withLabel),
|
|
12902
|
+
_step2;
|
|
12903
|
+
try {
|
|
12904
|
+
var _loop = function _loop() {
|
|
12905
|
+
var entry = _step2.value;
|
|
12906
|
+
var order = [entry.marker.preferredTextPosition].concat(_toConsumableArray(FALLBACK_ORDER.filter(function (position) {
|
|
12907
|
+
return position !== entry.marker.preferredTextPosition;
|
|
12908
|
+
})));
|
|
12909
|
+
var fit = order.map(function (position) {
|
|
12910
|
+
return {
|
|
12911
|
+
position: position,
|
|
12912
|
+
rect: computeCandidateRect(entry.iconRect, entry.labelSize, position, _this4.config.gapPx, _this4.config.verticalGapPx)
|
|
12913
|
+
};
|
|
12914
|
+
}).find(function (_ref2) {
|
|
12915
|
+
var rect = _ref2.rect;
|
|
12916
|
+
return !_this4.collides(rect, entry.marker, entries, placedLabels);
|
|
12917
|
+
});
|
|
12918
|
+
if (fit) {
|
|
12919
|
+
placedLabels.push(fit.rect);
|
|
12920
|
+
decisions.set(entry.marker, {
|
|
12921
|
+
position: fit.position,
|
|
12922
|
+
hidden: false
|
|
12923
|
+
});
|
|
12924
|
+
} else {
|
|
12925
|
+
decisions.set(entry.marker, {
|
|
12926
|
+
position: entry.marker.preferredTextPosition,
|
|
12927
|
+
hidden: true
|
|
12928
|
+
});
|
|
12929
|
+
}
|
|
12930
|
+
};
|
|
12931
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
12932
|
+
_loop();
|
|
12933
|
+
}
|
|
12934
|
+
} catch (err) {
|
|
12935
|
+
_iterator2.e(err);
|
|
12936
|
+
} finally {
|
|
12937
|
+
_iterator2.f();
|
|
12938
|
+
}
|
|
12939
|
+
return decisions;
|
|
12940
|
+
}
|
|
12941
|
+
|
|
12942
|
+
/**
|
|
12943
|
+
* Whether a candidate label rect clashes with any other marker's icon or
|
|
12944
|
+
* with a label already placed this pass.
|
|
12945
|
+
*
|
|
12946
|
+
* A label's own icon is deliberately excluded: `gapPx`/`verticalGapPx`
|
|
12947
|
+
* already define the spacing to it, and `paddingPx` is breathing room
|
|
12948
|
+
* against *neighbors*. Counting the own icon here would make top/bottom
|
|
12949
|
+
* impossible for every marker as soon as `paddingPx` exceeded
|
|
12950
|
+
* `verticalGapPx` (4 vs 4 by default) — and at `paddingPx: 10` would hide
|
|
12951
|
+
* every label on the map.
|
|
12952
|
+
*/
|
|
12953
|
+
}, {
|
|
12954
|
+
key: "collides",
|
|
12955
|
+
value: function collides(rect, self, entries, placedLabels) {
|
|
12956
|
+
var padded = expandRect(rect, this.config.paddingPx);
|
|
12957
|
+
return entries.some(function (other) {
|
|
12958
|
+
return other.marker !== self && rectsIntersect(padded, other.iconRect);
|
|
12959
|
+
}) || placedLabels.some(function (label) {
|
|
12960
|
+
return rectsIntersect(padded, label);
|
|
12961
|
+
});
|
|
12962
|
+
}
|
|
12963
|
+
|
|
12964
|
+
/** Write phase: only touches the DOM for markers whose decision actually changed. */
|
|
12965
|
+
}, {
|
|
12966
|
+
key: "applyDecisions",
|
|
12967
|
+
value: function applyDecisions(decisions) {
|
|
12968
|
+
var _this5 = this;
|
|
12969
|
+
decisions.forEach(function (decision, marker) {
|
|
12970
|
+
var last = _this5.lastAppliedState.get(marker);
|
|
12971
|
+
if (last && last.position === decision.position && last.hidden === decision.hidden) return;
|
|
12972
|
+
if (marker.textContainerEl) {
|
|
12973
|
+
MarkerUtils.applyTextPosition(marker.textContainerEl, decision.position, decision.hidden);
|
|
12974
|
+
}
|
|
12975
|
+
_this5.lastAppliedState.set(marker, decision);
|
|
12976
|
+
});
|
|
12977
|
+
}
|
|
12978
|
+
}]);
|
|
12979
|
+
}();
|
|
12980
|
+
function hasLabelSize(entry) {
|
|
12981
|
+
return entry.labelSize !== undefined;
|
|
12982
|
+
}
|
|
12389
12983
|
;// ./src/domain/models/routeInstance.ts
|
|
12390
12984
|
/**
|
|
12391
12985
|
* Represents the conditions for the step animation.
|
|
@@ -12615,10 +13209,10 @@ nav_functions_defineProperty(NavFunctions, "EARTH_RADIUS", 6378000);
|
|
|
12615
13209
|
function routeController_typeof(o) { "@babel/helpers - typeof"; return routeController_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, routeController_typeof(o); }
|
|
12616
13210
|
function routeController_ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
12617
13211
|
function routeController_objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? routeController_ownKeys(Object(t), !0).forEach(function (r) { routeController_defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : routeController_ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
12618
|
-
function
|
|
12619
|
-
function
|
|
12620
|
-
function
|
|
12621
|
-
function
|
|
13212
|
+
function routeController_toConsumableArray(r) { return routeController_arrayWithoutHoles(r) || routeController_iterableToArray(r) || routeController_unsupportedIterableToArray(r) || routeController_nonIterableSpread(); }
|
|
13213
|
+
function routeController_nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
13214
|
+
function routeController_iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
|
|
13215
|
+
function routeController_arrayWithoutHoles(r) { if (Array.isArray(r)) return routeController_arrayLikeToArray(r); }
|
|
12622
13216
|
function routeController_createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = routeController_unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
12623
13217
|
function routeController_unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return routeController_arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? routeController_arrayLikeToArray(r, a) : void 0; } }
|
|
12624
13218
|
function routeController_arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
@@ -13045,7 +13639,7 @@ var RouteController = /*#__PURE__*/function () {
|
|
|
13045
13639
|
throw new Error("Error: position array has different length than colors array");
|
|
13046
13640
|
}
|
|
13047
13641
|
var stops = createStops(positionsToUse, colors);
|
|
13048
|
-
var gradient = ["interpolate", ["linear"], ["line-progress"]].concat(
|
|
13642
|
+
var gradient = ["interpolate", ["linear"], ["line-progress"]].concat(routeController_toConsumableArray(stops));
|
|
13049
13643
|
return {
|
|
13050
13644
|
"line-color": null,
|
|
13051
13645
|
"line-gradient": gradient,
|
|
@@ -13156,25 +13750,49 @@ var RouteController = /*#__PURE__*/function () {
|
|
|
13156
13750
|
}
|
|
13157
13751
|
|
|
13158
13752
|
/**
|
|
13159
|
-
*
|
|
13160
|
-
*
|
|
13753
|
+
* Every active route's marker. Used by `MarkerLayoutController` so marker
|
|
13754
|
+
* labels are never placed on top of a route's own marker.
|
|
13755
|
+
* @internal
|
|
13161
13756
|
*/
|
|
13162
13757
|
}, {
|
|
13163
|
-
key: "
|
|
13164
|
-
value: function
|
|
13758
|
+
key: "getRouteMarkers",
|
|
13759
|
+
value: function getRouteMarkers() {
|
|
13760
|
+
var markers = [];
|
|
13165
13761
|
var _iterator6 = routeController_createForOfIteratorHelper(this.routes.values()),
|
|
13166
13762
|
_step6;
|
|
13167
13763
|
try {
|
|
13168
13764
|
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
13169
|
-
var _instance$routeMarker, _instance$routeMarker2, _instance$routeMarker3;
|
|
13170
13765
|
var instance = _step6.value;
|
|
13171
|
-
|
|
13766
|
+
if (instance.routeMarker) markers.push(instance.routeMarker);
|
|
13172
13767
|
}
|
|
13173
13768
|
} catch (err) {
|
|
13174
13769
|
_iterator6.e(err);
|
|
13175
13770
|
} finally {
|
|
13176
13771
|
_iterator6.f();
|
|
13177
13772
|
}
|
|
13773
|
+
return markers;
|
|
13774
|
+
}
|
|
13775
|
+
|
|
13776
|
+
/**
|
|
13777
|
+
* Update the visibility of route markers for all active routes.
|
|
13778
|
+
* @param floorId The floor ID to update the visibility for.
|
|
13779
|
+
*/
|
|
13780
|
+
}, {
|
|
13781
|
+
key: "updateRouteMarkerVisibility",
|
|
13782
|
+
value: function updateRouteMarkerVisibility(floorId) {
|
|
13783
|
+
var _iterator7 = routeController_createForOfIteratorHelper(this.routes.values()),
|
|
13784
|
+
_step7;
|
|
13785
|
+
try {
|
|
13786
|
+
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
|
13787
|
+
var _instance$routeMarker, _instance$routeMarker2, _instance$routeMarker3;
|
|
13788
|
+
var instance = _step7.value;
|
|
13789
|
+
((_instance$routeMarker = instance.routeMarker) === null || _instance$routeMarker === void 0 ? void 0 : _instance$routeMarker.floorId) === floorId ? (_instance$routeMarker2 = instance.routeMarker) === null || _instance$routeMarker2 === void 0 ? void 0 : _instance$routeMarker2.show(this.map) : (_instance$routeMarker3 = instance.routeMarker) === null || _instance$routeMarker3 === void 0 ? void 0 : _instance$routeMarker3.hide();
|
|
13790
|
+
}
|
|
13791
|
+
} catch (err) {
|
|
13792
|
+
_iterator7.e(err);
|
|
13793
|
+
} finally {
|
|
13794
|
+
_iterator7.f();
|
|
13795
|
+
}
|
|
13178
13796
|
}
|
|
13179
13797
|
}, {
|
|
13180
13798
|
key: "updatePlaceFloorForRouting",
|
|
@@ -13293,7 +13911,7 @@ var RouteController = /*#__PURE__*/function () {
|
|
|
13293
13911
|
this.removeSourcesAndLayersForRoute(instance);
|
|
13294
13912
|
this.routes["delete"](instance.id);
|
|
13295
13913
|
if (this.lastAddedRouteId === instance.id) {
|
|
13296
|
-
var remaining =
|
|
13914
|
+
var remaining = routeController_toConsumableArray(this.routes.keys());
|
|
13297
13915
|
this.lastAddedRouteId = remaining.length > 0 ? remaining[remaining.length - 1] : undefined;
|
|
13298
13916
|
}
|
|
13299
13917
|
this.syncRouteCollision();
|
|
@@ -13305,18 +13923,18 @@ var RouteController = /*#__PURE__*/function () {
|
|
|
13305
13923
|
}, {
|
|
13306
13924
|
key: "removeAllRoutes",
|
|
13307
13925
|
value: function removeAllRoutes() {
|
|
13308
|
-
var
|
|
13309
|
-
|
|
13926
|
+
var _iterator8 = routeController_createForOfIteratorHelper(this.routes.values()),
|
|
13927
|
+
_step8;
|
|
13310
13928
|
try {
|
|
13311
|
-
for (
|
|
13312
|
-
var instance =
|
|
13929
|
+
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
|
13930
|
+
var instance = _step8.value;
|
|
13313
13931
|
this.clearRouteInstance(instance);
|
|
13314
13932
|
this.removeSourcesAndLayersForRoute(instance);
|
|
13315
13933
|
}
|
|
13316
13934
|
} catch (err) {
|
|
13317
|
-
|
|
13935
|
+
_iterator8.e(err);
|
|
13318
13936
|
} finally {
|
|
13319
|
-
|
|
13937
|
+
_iterator8.f();
|
|
13320
13938
|
}
|
|
13321
13939
|
this.routes.clear();
|
|
13322
13940
|
this.lastAddedRouteId = undefined;
|
|
@@ -13330,7 +13948,7 @@ var RouteController = /*#__PURE__*/function () {
|
|
|
13330
13948
|
}, {
|
|
13331
13949
|
key: "getRouteIds",
|
|
13332
13950
|
value: function getRouteIds() {
|
|
13333
|
-
return
|
|
13951
|
+
return routeController_toConsumableArray(this.routes.keys());
|
|
13334
13952
|
}
|
|
13335
13953
|
}, {
|
|
13336
13954
|
key: "internalPause",
|
|
@@ -14551,6 +15169,8 @@ var Loggeable = /*#__PURE__*/function () {
|
|
|
14551
15169
|
}]);
|
|
14552
15170
|
}();
|
|
14553
15171
|
;// ./src/domain/models/mapConfig.ts
|
|
15172
|
+
|
|
15173
|
+
|
|
14554
15174
|
/**
|
|
14555
15175
|
* Configuration options for map tile caching.
|
|
14556
15176
|
* Allows controlling how map tiles are cached in memory and persisted via service worker.
|
|
@@ -14593,6 +15213,40 @@ var DEFAULT_TILE_CACHE_CONFIG = {
|
|
|
14593
15213
|
*/
|
|
14594
15214
|
var MAPLIBRE_MAX_TILE_CACHE_HARD_CAP = 100000;
|
|
14595
15215
|
|
|
15216
|
+
/**
|
|
15217
|
+
* Configuration for automatic marker label collision avoidance.
|
|
15218
|
+
*
|
|
15219
|
+
* When enabled, a marker's text label (see `MarkerConfig.textPosition`) is
|
|
15220
|
+
* treated as a preferred starting side rather than a fixed placement: the
|
|
15221
|
+
* SDK checks it against neighboring markers' icons and labels, moves it to
|
|
15222
|
+
* a free side (right/top/left/bottom) when its preferred side is occupied,
|
|
15223
|
+
* and hides it entirely when no side is collision-free. The marker's icon
|
|
15224
|
+
* itself never moves.
|
|
15225
|
+
*
|
|
15226
|
+
* @example
|
|
15227
|
+
* ```typescript
|
|
15228
|
+
* const markerLayoutConfig: MarkerLayoutConfig = {
|
|
15229
|
+
* enabled: true,
|
|
15230
|
+
* gapPx: 8,
|
|
15231
|
+
* maxLabelWidthPx: 160,
|
|
15232
|
+
* };
|
|
15233
|
+
* ```
|
|
15234
|
+
*
|
|
15235
|
+
* @group Configuration
|
|
15236
|
+
*/
|
|
15237
|
+
|
|
15238
|
+
/**
|
|
15239
|
+
* Default values for marker layout configuration
|
|
15240
|
+
* @internal
|
|
15241
|
+
*/
|
|
15242
|
+
var DEFAULT_MARKER_LAYOUT_CONFIG = {
|
|
15243
|
+
enabled: true,
|
|
15244
|
+
gapPx: 8,
|
|
15245
|
+
verticalGapPx: 4,
|
|
15246
|
+
paddingPx: 4,
|
|
15247
|
+
maxLabelWidthPx: DEFAULT_MAX_LABEL_WIDTH_PX
|
|
15248
|
+
};
|
|
15249
|
+
|
|
14596
15250
|
/**
|
|
14597
15251
|
* Basic configuration for the map.
|
|
14598
15252
|
* Provides essential settings for initializing and customizing map behavior.
|
|
@@ -14642,6 +15296,7 @@ var MAPLIBRE_MAX_TILE_CACHE_HARD_CAP = 100000;
|
|
|
14642
15296
|
* @property authToken - (Optional) Authentication token for accessing protected map resources. Required for loading map related data from Portal.
|
|
14643
15297
|
* @property apiUrl - (Optional) Injected by SDK when creating map; base API URL for map requests.
|
|
14644
15298
|
* @property mapvxRequestContext - (Optional) Injected by SDK when creating map; context sent as headers to public-api.mapvx.com.
|
|
15299
|
+
* @property markerLayout - (Optional) Automatic marker label collision avoidance configuration.
|
|
14645
15300
|
*/
|
|
14646
15301
|
;// ./node_modules/.pnpm/@googlemaps+polyline-codec@1.0.28/node_modules/@googlemaps/polyline-codec/dist/index.esm.js
|
|
14647
15302
|
/**
|
|
@@ -15343,8 +15998,9 @@ function MVXTransport(data) {
|
|
|
15343
15998
|
;// ./src/utils/mapvxHostname.ts
|
|
15344
15999
|
/**
|
|
15345
16000
|
* Returns whether a URL hostname is part of the MapVX API domain tree.
|
|
15346
|
-
* Matches `mapvx.com` and any subdomain (`api.mapvx.com`,
|
|
15347
|
-
* `
|
|
16001
|
+
* Matches `mapvx.com` and `mapvx.dev` plus any subdomain (`api.mapvx.com`,
|
|
16002
|
+
* `public-api.mapvx.com`, `api.mapvx.dev`, `portal.mapvx.dev`, etc.).
|
|
16003
|
+
* Does not match lookalike domains (e.g. `notmapvx.com`).
|
|
15348
16004
|
*
|
|
15349
16005
|
* @param hostname - Value from `URL.hostname` (no port)
|
|
15350
16006
|
* @returns True if context headers should be attached for this host
|
|
@@ -15355,7 +16011,7 @@ function isMapVxRequestHostname(hostname) {
|
|
|
15355
16011
|
if (!h) {
|
|
15356
16012
|
return false;
|
|
15357
16013
|
}
|
|
15358
|
-
return /^(?:[a-z0-9-]+\.)*mapvx\.com$/.test(h);
|
|
16014
|
+
return /^(?:[a-z0-9-]+\.)*mapvx\.(?:com|dev)$/.test(h);
|
|
15359
16015
|
}
|
|
15360
16016
|
;// ./src/repository/requester.ts
|
|
15361
16017
|
function requester_toConsumableArray(r) { return requester_arrayWithoutHoles(r) || requester_iterableToArray(r) || requester_unsupportedIterableToArray(r) || requester_nonIterableSpread(); }
|
|
@@ -19835,6 +20491,7 @@ function convertPaddingToPixels(padding, containerWidth, containerHeight) {
|
|
|
19835
20491
|
|
|
19836
20492
|
|
|
19837
20493
|
|
|
20494
|
+
|
|
19838
20495
|
/**
|
|
19839
20496
|
* @group Map
|
|
19840
20497
|
*/
|
|
@@ -19908,6 +20565,12 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
19908
20565
|
merged.maxTiles = Math.min(merged.maxTiles, MAPLIBRE_MAX_TILE_CACHE_HARD_CAP);
|
|
19909
20566
|
return merged;
|
|
19910
20567
|
}();
|
|
20568
|
+
_this.markerLayoutConfig = map_objectSpread(map_objectSpread({}, DEFAULT_MARKER_LAYOUT_CONFIG), mapConfig.markerLayout);
|
|
20569
|
+
_this.markerLayoutController = new MarkerLayoutController(_this, _this.markerLayoutConfig);
|
|
20570
|
+
// `container` is the very element handed to MapLibre below, and every
|
|
20571
|
+
// marker is mounted inside it, so publishing the gap/width variables here
|
|
20572
|
+
// covers markers added before the map's "load" event fires.
|
|
20573
|
+
_this.markerLayoutController.applyLayoutVariables(container);
|
|
19911
20574
|
if (mapConfig.parentPlaceId != null) {
|
|
19912
20575
|
_this.initialPlaceDetailSetUp(mapConfig.parentPlaceId, mapConfig.authToken);
|
|
19913
20576
|
}
|
|
@@ -20075,6 +20738,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
20075
20738
|
(_mapConfig$onMapReady = mapConfig.onMapReady) === null || _mapConfig$onMapReady === void 0 || _mapConfig$onMapReady.call(mapConfig);
|
|
20076
20739
|
_this6.onHover();
|
|
20077
20740
|
_this6.subscribeToFailedTiles();
|
|
20741
|
+
_this6.markerLayoutController.attach();
|
|
20078
20742
|
});
|
|
20079
20743
|
// Self-healing for circles: a full style reload wipes custom sources and
|
|
20080
20744
|
// layers, and not every restyle path goes through whenStyleUpdates.
|
|
@@ -20182,6 +20846,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
20182
20846
|
key: "destroyMap",
|
|
20183
20847
|
value: function destroyMap() {
|
|
20184
20848
|
this.circles = [];
|
|
20849
|
+
this.markerLayoutController.destroy();
|
|
20185
20850
|
this.map.remove();
|
|
20186
20851
|
this.unsubscribeFromFailedTiles();
|
|
20187
20852
|
}
|
|
@@ -20373,12 +21038,31 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
20373
21038
|
this.filterByFloorKey(this.currentFloor);
|
|
20374
21039
|
(_this$scene3D4 = this.scene3D) === null || _this$scene3D4 === void 0 || _this$scene3D4.refreshOverlay(this.currentFloor);
|
|
20375
21040
|
}
|
|
21041
|
+
|
|
21042
|
+
/**
|
|
21043
|
+
* Internal accessor for every marker currently on the map, used by
|
|
21044
|
+
* {@link MarkerLayoutController} to compute collision avoidance. Not part
|
|
21045
|
+
* of the public `MapVXMap` interface.
|
|
21046
|
+
*
|
|
21047
|
+
* The user-location marker and the route controller's markers live outside
|
|
21048
|
+
* `this.markers`, but they still occupy screen space — leaving them out
|
|
21049
|
+
* would let labels be placed straight on top of them. They carry no label
|
|
21050
|
+
* of their own, so they only ever act as obstacles.
|
|
21051
|
+
* @internal
|
|
21052
|
+
*/
|
|
21053
|
+
}, {
|
|
21054
|
+
key: "getMarkers",
|
|
21055
|
+
value: function getMarkers() {
|
|
21056
|
+
var unmanaged = this.routeController.getRouteMarkers();
|
|
21057
|
+
if (this.userLocationMarker) unmanaged.push(this.userLocationMarker);
|
|
21058
|
+
return unmanaged.length > 0 ? [].concat(map_toConsumableArray(this.markers), map_toConsumableArray(unmanaged)) : this.markers;
|
|
21059
|
+
}
|
|
20376
21060
|
}, {
|
|
20377
21061
|
key: "addMarker",
|
|
20378
21062
|
value: function addMarker(marker) {
|
|
20379
21063
|
var _this1 = this;
|
|
20380
21064
|
try {
|
|
20381
|
-
var _this$innerFloors$fin4, _this$innerFloors$fin5;
|
|
21065
|
+
var _marker$maxLabelWidth, _this$innerFloors$fin4, _this$innerFloors$fin5;
|
|
20382
21066
|
// Check if a marker with the same ID already exists and remove it
|
|
20383
21067
|
if (marker.id) {
|
|
20384
21068
|
var existingMarkerIndex = this.markers.findIndex(function (m) {
|
|
@@ -20394,12 +21078,15 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
20394
21078
|
});
|
|
20395
21079
|
}
|
|
20396
21080
|
}
|
|
20397
|
-
var markerCreated = new MarkerAttribute(marker)
|
|
21081
|
+
var markerCreated = new MarkerAttribute(map_objectSpread(map_objectSpread({}, marker), {}, {
|
|
21082
|
+
maxLabelWidthPx: (_marker$maxLabelWidth = marker.maxLabelWidthPx) !== null && _marker$maxLabelWidth !== void 0 ? _marker$maxLabelWidth : this.markerLayoutConfig.maxLabelWidthPx
|
|
21083
|
+
}));
|
|
20398
21084
|
var isOutdoor = !this.parentPlace || ((_this$innerFloors$fin4 = (_this$innerFloors$fin5 = this.innerFloors.find(function (floor) {
|
|
20399
21085
|
return floor.key === _this1.currentFloor;
|
|
20400
21086
|
})) === null || _this$innerFloors$fin5 === void 0 ? void 0 : _this$innerFloors$fin5.reachableFromGPS) !== null && _this$innerFloors$fin4 !== void 0 ? _this$innerFloors$fin4 : false);
|
|
20401
21087
|
markerCreated.changeFloor(this.currentFloor, this.map, isOutdoor);
|
|
20402
21088
|
this.markers.push(markerCreated);
|
|
21089
|
+
this.markerLayoutController.scheduleRelayout();
|
|
20403
21090
|
this.logEvent("addMarker");
|
|
20404
21091
|
return markerCreated.id;
|
|
20405
21092
|
} catch (error) {
|
|
@@ -20418,6 +21105,8 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
20418
21105
|
});
|
|
20419
21106
|
if (_marker !== undefined) {
|
|
20420
21107
|
_marker.updateIcon(markerConfig);
|
|
21108
|
+
this.markerLayoutController.invalidateMarker(_marker);
|
|
21109
|
+
this.markerLayoutController.scheduleRelayout();
|
|
20421
21110
|
}
|
|
20422
21111
|
this.logEvent("updateMarker");
|
|
20423
21112
|
return (_marker$id = _marker === null || _marker === void 0 ? void 0 : _marker.id) !== null && _marker$id !== void 0 ? _marker$id : "";
|
|
@@ -20436,6 +21125,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
20436
21125
|
});
|
|
20437
21126
|
if (_marker2 !== undefined) {
|
|
20438
21127
|
_marker2.setLngLat(newPosition);
|
|
21128
|
+
this.markerLayoutController.scheduleRelayout();
|
|
20439
21129
|
}
|
|
20440
21130
|
this.logEvent("updateMarkerPosition");
|
|
20441
21131
|
} catch (error) {
|
|
@@ -20453,6 +21143,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
20453
21143
|
});
|
|
20454
21144
|
if (_marker3 !== null && this.map) {
|
|
20455
21145
|
_marker3 === null || _marker3 === void 0 || _marker3.show(this.map);
|
|
21146
|
+
this.markerLayoutController.scheduleRelayout();
|
|
20456
21147
|
}
|
|
20457
21148
|
this.logEvent("showMarker");
|
|
20458
21149
|
} catch (error) {
|
|
@@ -20468,6 +21159,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
20468
21159
|
});
|
|
20469
21160
|
if (_marker4 !== null) {
|
|
20470
21161
|
_marker4 === null || _marker4 === void 0 || _marker4.hide();
|
|
21162
|
+
this.markerLayoutController.scheduleRelayout();
|
|
20471
21163
|
}
|
|
20472
21164
|
this.logEvent("hideMarker");
|
|
20473
21165
|
} catch (error) {
|
|
@@ -20486,6 +21178,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
20486
21178
|
this.markers = this.markers.filter(function (e) {
|
|
20487
21179
|
return e.id !== markerId;
|
|
20488
21180
|
});
|
|
21181
|
+
this.markerLayoutController.scheduleRelayout();
|
|
20489
21182
|
}
|
|
20490
21183
|
this.logEvent("removeMarker");
|
|
20491
21184
|
} catch (error) {
|
|
@@ -20502,6 +21195,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
20502
21195
|
marker.remove();
|
|
20503
21196
|
});
|
|
20504
21197
|
this.markers = [];
|
|
21198
|
+
this.markerLayoutController.scheduleRelayout();
|
|
20505
21199
|
this.logEvent("removeAllMarkers");
|
|
20506
21200
|
} catch (error) {
|
|
20507
21201
|
throw new Error("Failed to remove all markers", {
|
|
@@ -20935,6 +21629,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
20935
21629
|
this.markers.forEach(function (e) {
|
|
20936
21630
|
e.changeFloor(floorId, _this10.map, isOutdoor);
|
|
20937
21631
|
});
|
|
21632
|
+
this.markerLayoutController.scheduleRelayout();
|
|
20938
21633
|
}
|
|
20939
21634
|
}, {
|
|
20940
21635
|
key: "updateFiltersTo",
|
|
@@ -22008,6 +22703,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
22008
22703
|
}, {
|
|
22009
22704
|
key: "addUserLocationTracking",
|
|
22010
22705
|
value: function addUserLocationTracking(enableHighAccuracy, geoLocation, icon) {
|
|
22706
|
+
var _this14 = this;
|
|
22011
22707
|
var initialCoordinate = {
|
|
22012
22708
|
lat: 0.0,
|
|
22013
22709
|
lng: 0.0
|
|
@@ -22028,8 +22724,10 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
22028
22724
|
var marker = new MarkerAttribute(markerConfig);
|
|
22029
22725
|
marker.addToMap(this.map);
|
|
22030
22726
|
this.userLocationMarker = marker;
|
|
22727
|
+
this.markerLayoutController.scheduleRelayout();
|
|
22031
22728
|
var updateMarker = function updateMarker(position) {
|
|
22032
22729
|
marker.setLngLat([position.coords.longitude, position.coords.latitude]);
|
|
22730
|
+
_this14.markerLayoutController.scheduleRelayout();
|
|
22033
22731
|
};
|
|
22034
22732
|
this.geoLocation = geoLocation !== null && geoLocation !== void 0 ? geoLocation : navigator.geolocation;
|
|
22035
22733
|
this.watchPositionID = this.geoLocation.watchPosition(updateMarker, function (error) {
|
|
@@ -22044,6 +22742,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
22044
22742
|
if (this.userLocationMarker !== undefined) {
|
|
22045
22743
|
this.userLocationMarker.remove();
|
|
22046
22744
|
this.userLocationMarker = undefined;
|
|
22745
|
+
this.markerLayoutController.scheduleRelayout();
|
|
22047
22746
|
|
|
22048
22747
|
// Check if watchPosition ID is valid and stop tracking
|
|
22049
22748
|
if (this.watchPositionID) {
|
|
@@ -22112,7 +22811,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
22112
22811
|
key: "onWebGLContextLost",
|
|
22113
22812
|
value: function onWebGLContextLost(e) {
|
|
22114
22813
|
var _this$map,
|
|
22115
|
-
|
|
22814
|
+
_this15 = this;
|
|
22116
22815
|
e.originalEvent.preventDefault();
|
|
22117
22816
|
console.warn("Contexto WebGL perdido 😢");
|
|
22118
22817
|
|
|
@@ -22123,8 +22822,8 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
22123
22822
|
var _ext$restoreContext;
|
|
22124
22823
|
canvas.addEventListener("webglcontextrestored", function () {
|
|
22125
22824
|
console.debug("Contexto WebGL restaurado, forzando re-render");
|
|
22126
|
-
|
|
22127
|
-
|
|
22825
|
+
_this15.map.triggerRepaint(); // forzar repaint
|
|
22826
|
+
_this15.failedTiles.clear();
|
|
22128
22827
|
}, {
|
|
22129
22828
|
once: true
|
|
22130
22829
|
});
|
|
@@ -22164,7 +22863,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
22164
22863
|
}, {
|
|
22165
22864
|
key: "subscribeToFailedTiles",
|
|
22166
22865
|
value: function subscribeToFailedTiles() {
|
|
22167
|
-
var
|
|
22866
|
+
var _this16 = this;
|
|
22168
22867
|
if (this.retryTimer) return;
|
|
22169
22868
|
|
|
22170
22869
|
// Store bound functions for proper cleanup
|
|
@@ -22173,20 +22872,20 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
22173
22872
|
this.boundOnWebGLContextLost = this.onWebGLContextLost.bind(this);
|
|
22174
22873
|
this.boundOnWebGLContextRestored = this.onWebGLContextRestored.bind(this);
|
|
22175
22874
|
this.retryTimer = setInterval(function () {
|
|
22176
|
-
if (!
|
|
22177
|
-
|
|
22875
|
+
if (!_this16.map.getSource("indoorequal")) {
|
|
22876
|
+
_this16.failedTiles.clear();
|
|
22178
22877
|
return;
|
|
22179
22878
|
}
|
|
22180
|
-
var source =
|
|
22879
|
+
var source = _this16.map.getSource("indoorequal");
|
|
22181
22880
|
if (!source || source.type !== "vector") {
|
|
22182
|
-
|
|
22881
|
+
_this16.failedTiles.clear();
|
|
22183
22882
|
return;
|
|
22184
22883
|
}
|
|
22185
22884
|
|
|
22186
22885
|
// Process tiles and remove invalid ones
|
|
22187
22886
|
var tilesToRetry = [];
|
|
22188
22887
|
var tilesToRemove = [];
|
|
22189
|
-
|
|
22888
|
+
_this16.failedTiles.forEach(function (tile) {
|
|
22190
22889
|
// Check if tile is still valid before attempting reload
|
|
22191
22890
|
if (!tile || tile.state === "unloaded" || tile.state === "loading") {
|
|
22192
22891
|
tilesToRemove.push(tile);
|
|
@@ -22204,14 +22903,14 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
22204
22903
|
|
|
22205
22904
|
// Remove invalid tiles from the set
|
|
22206
22905
|
tilesToRemove.forEach(function (tile) {
|
|
22207
|
-
return
|
|
22906
|
+
return _this16.failedTiles["delete"](tile);
|
|
22208
22907
|
});
|
|
22209
22908
|
|
|
22210
22909
|
// Attempt to reload valid failed tiles
|
|
22211
22910
|
var now = Date.now();
|
|
22212
22911
|
tilesToRetry.forEach(function (tile) {
|
|
22213
|
-
var
|
|
22214
|
-
var retry = (
|
|
22912
|
+
var _this16$tileRetryStat;
|
|
22913
|
+
var retry = (_this16$tileRetryStat = _this16.tileRetryState.get(tile)) !== null && _this16$tileRetryStat !== void 0 ? _this16$tileRetryStat : {
|
|
22215
22914
|
attempts: 0,
|
|
22216
22915
|
nextAttemptAt: 0,
|
|
22217
22916
|
pending: false
|
|
@@ -22222,16 +22921,16 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
22222
22921
|
var onFailure = function onFailure(error) {
|
|
22223
22922
|
var attempts = retry.attempts + 1;
|
|
22224
22923
|
if (attempts >= MAX_TILE_RETRIES) {
|
|
22225
|
-
|
|
22226
|
-
|
|
22227
|
-
|
|
22924
|
+
_this16.debugLog("Tile reload failed ".concat(attempts, " times, dropping it from the retry queue"), error);
|
|
22925
|
+
_this16.failedTiles["delete"](tile);
|
|
22926
|
+
_this16.tileRetryState["delete"](tile);
|
|
22228
22927
|
return;
|
|
22229
22928
|
}
|
|
22230
22929
|
|
|
22231
22930
|
// Stay in the queue and try again once the backoff has elapsed.
|
|
22232
22931
|
var backoffMs = TILE_RETRY_BASE_DELAY_MS * Math.pow(2, attempts - 1);
|
|
22233
|
-
|
|
22234
|
-
|
|
22932
|
+
_this16.debugLog("Tile reload failed (attempt ".concat(attempts, "/").concat(MAX_TILE_RETRIES, "), retrying in ").concat(backoffMs, "ms"), error);
|
|
22933
|
+
_this16.tileRetryState.set(tile, {
|
|
22235
22934
|
attempts: attempts,
|
|
22236
22935
|
nextAttemptAt: Date.now() + backoffMs,
|
|
22237
22936
|
pending: false
|
|
@@ -22240,7 +22939,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
22240
22939
|
try {
|
|
22241
22940
|
// Verify tile still exists and is in a retryable state
|
|
22242
22941
|
if (tile && (tile.state === "errored" || tile.state === "expired")) {
|
|
22243
|
-
|
|
22942
|
+
_this16.tileRetryState.set(tile, map_objectSpread(map_objectSpread({}, retry), {}, {
|
|
22244
22943
|
pending: true
|
|
22245
22944
|
}));
|
|
22246
22945
|
// loadTile is async, so a rejection escapes this try/catch and has to be handled
|
|
@@ -22250,7 +22949,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
22250
22949
|
// Loaded: forget the attempt history so a later failure starts from zero. The
|
|
22251
22950
|
// tile leaves the queue through the tilesToRemove branch on the next tick,
|
|
22252
22951
|
// once its state is no longer errored/expired.
|
|
22253
|
-
|
|
22952
|
+
_this16.tileRetryState["delete"](tile);
|
|
22254
22953
|
})["catch"](onFailure);
|
|
22255
22954
|
}
|
|
22256
22955
|
} catch (error) {
|