@mapvx/web-js 1.1.1 → 1.2.0
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/domain/models/circle.js +218 -0
- package/dist/cjs/domain/models/circle.js.map +1 -0
- package/dist/cjs/index.js +7 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/logger/logger.js +1 -1
- package/dist/cjs/logger/rollbar.js +1 -1
- package/dist/cjs/map/map.js +274 -3
- package/dist/cjs/map/map.js.map +1 -1
- package/dist/es/domain/models/circle.d.ts +183 -0
- package/dist/es/domain/models/circle.d.ts.map +1 -0
- package/dist/es/domain/models/circle.js +212 -0
- package/dist/es/domain/models/circle.js.map +1 -0
- package/dist/es/index.d.ts +2 -0
- package/dist/es/index.d.ts.map +1 -1
- package/dist/es/index.js +2 -0
- package/dist/es/index.js.map +1 -1
- package/dist/es/logger/logger.js +1 -1
- package/dist/es/logger/rollbar.js +1 -1
- package/dist/es/map/map.d.ts +196 -0
- package/dist/es/map/map.d.ts.map +1 -1
- package/dist/es/map/map.js +274 -3
- package/dist/es/map/map.js.map +1 -1
- package/dist/umd/index.js +551 -16
- package/dist/umd/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.circleRing = exports.resolveCircleConfig = exports.isValidCircleConfig = exports.CIRCLE_DEFAULTS = exports.MAPVX_BRAND_COLOR = void 0;
|
|
4
|
+
const utils_1 = require("../../utils/utils");
|
|
5
|
+
/**
|
|
6
|
+
* MapVX brand color used as the default for circle styling and other
|
|
7
|
+
* SDK-drawn overlays (colored places, borders).
|
|
8
|
+
*
|
|
9
|
+
* @group Circles
|
|
10
|
+
*/
|
|
11
|
+
exports.MAPVX_BRAND_COLOR = "#276EF1";
|
|
12
|
+
/**
|
|
13
|
+
* Default styling values applied to a circle when the corresponding
|
|
14
|
+
* {@link CircleConfig} fields are omitted.
|
|
15
|
+
*
|
|
16
|
+
* @group Circles
|
|
17
|
+
*/
|
|
18
|
+
exports.CIRCLE_DEFAULTS = {
|
|
19
|
+
fillColor: exports.MAPVX_BRAND_COLOR,
|
|
20
|
+
fillOpacity: 0.14,
|
|
21
|
+
strokeColor: exports.MAPVX_BRAND_COLOR,
|
|
22
|
+
strokeWidth: 2,
|
|
23
|
+
strokeOpacity: 0.65,
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Validates that a radius in meters is positive and finite.
|
|
27
|
+
* @param radius The radius value to validate.
|
|
28
|
+
* @throws {Error} If radius is ≤ 0 or not finite (NaN/Infinity).
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
31
|
+
function validateRadiusMeters(radius) {
|
|
32
|
+
if (!Number.isFinite(radius) || radius <= 0) {
|
|
33
|
+
throw new Error(`Invalid radiusMeters: ${radius}. Must be a positive finite number.`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Validates that a coordinate is within valid geographic bounds.
|
|
38
|
+
* @param coord The coordinate to validate.
|
|
39
|
+
* @throws {Error} If latitude is outside [-90, 90] or longitude outside [-180, 180], or not finite.
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
42
|
+
function validateCoordinate(coord) {
|
|
43
|
+
if (coord == null || typeof coord !== "object") {
|
|
44
|
+
throw new Error("Invalid coordinate: expected an object with lat and lng properties.");
|
|
45
|
+
}
|
|
46
|
+
if (!Number.isFinite(coord.lat) ||
|
|
47
|
+
!Number.isFinite(coord.lng) ||
|
|
48
|
+
coord.lat < -90 ||
|
|
49
|
+
coord.lat > 90 ||
|
|
50
|
+
coord.lng < -180 ||
|
|
51
|
+
coord.lng > 180) {
|
|
52
|
+
throw new Error(`Invalid coordinate: lat=${coord.lat}, lng=${coord.lng}. ` +
|
|
53
|
+
`latitude must be in [-90, 90], longitude in [-180, 180], and both finite.`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Clamps an opacity value to the valid range [0, 1].
|
|
58
|
+
* @param opacity The opacity value to clamp.
|
|
59
|
+
* @param defaultValue Value to use if opacity is not a finite number.
|
|
60
|
+
* @returns The clamped opacity value.
|
|
61
|
+
* @internal
|
|
62
|
+
*/
|
|
63
|
+
function clampOpacity(opacity, defaultValue) {
|
|
64
|
+
if (!Number.isFinite(opacity))
|
|
65
|
+
return defaultValue;
|
|
66
|
+
return Math.max(0, Math.min(1, opacity));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Type guard for validating circle configurations without throwing.
|
|
70
|
+
* Returns true if the configuration is valid and can be added to the map.
|
|
71
|
+
*
|
|
72
|
+
* @param config Configuration to validate.
|
|
73
|
+
* @returns True if config is a valid CircleConfig, false otherwise.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* if (isValidCircleConfig(userInput)) {
|
|
78
|
+
* map.addCircle(userInput);
|
|
79
|
+
* } else {
|
|
80
|
+
* console.error('Invalid circle configuration');
|
|
81
|
+
* }
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* @group Circles
|
|
85
|
+
*/
|
|
86
|
+
function isValidCircleConfig(config) {
|
|
87
|
+
if (config === null || config === undefined || typeof config !== "object") {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
const c = config;
|
|
91
|
+
if (typeof c.coordinate !== "object" || c.coordinate === null)
|
|
92
|
+
return false;
|
|
93
|
+
const coord = c.coordinate;
|
|
94
|
+
if (typeof coord.lat !== "number" ||
|
|
95
|
+
typeof coord.lng !== "number" ||
|
|
96
|
+
!Number.isFinite(coord.lat) ||
|
|
97
|
+
!Number.isFinite(coord.lng) ||
|
|
98
|
+
coord.lat < -90 ||
|
|
99
|
+
coord.lat > 90 ||
|
|
100
|
+
coord.lng < -180 ||
|
|
101
|
+
coord.lng > 180) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
if (typeof c.radiusMeters !== "number" ||
|
|
105
|
+
!Number.isFinite(c.radiusMeters) ||
|
|
106
|
+
c.radiusMeters <= 0) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
if (c.id !== undefined && typeof c.id !== "string")
|
|
110
|
+
return false;
|
|
111
|
+
if (c.fillColor !== undefined && typeof c.fillColor !== "string")
|
|
112
|
+
return false;
|
|
113
|
+
if (c.fillOpacity !== undefined) {
|
|
114
|
+
if (typeof c.fillOpacity !== "number" || !Number.isFinite(c.fillOpacity))
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
if (c.strokeColor !== undefined && typeof c.strokeColor !== "string")
|
|
118
|
+
return false;
|
|
119
|
+
if (c.strokeWidth !== undefined) {
|
|
120
|
+
if (typeof c.strokeWidth !== "number" || !Number.isFinite(c.strokeWidth))
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
if (c.strokeOpacity !== undefined) {
|
|
124
|
+
if (typeof c.strokeOpacity !== "number" || !Number.isFinite(c.strokeOpacity))
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
if (c.floorId !== undefined && typeof c.floorId !== "string")
|
|
128
|
+
return false;
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
exports.isValidCircleConfig = isValidCircleConfig;
|
|
132
|
+
/**
|
|
133
|
+
* Resolves a {@link CircleConfig} into a {@link CircleRecord}, applying
|
|
134
|
+
* default styling, generating an id when one is not provided, and validating inputs.
|
|
135
|
+
*
|
|
136
|
+
* @param config Circle configuration provided by the SDK consumer.
|
|
137
|
+
* @param hidden Initial hidden state, defaults to visible.
|
|
138
|
+
* @returns The resolved circle record ready to be stored and rendered.
|
|
139
|
+
* @throws {Error} If radiusMeters is ≤ 0, not finite, or coordinates are invalid.
|
|
140
|
+
*
|
|
141
|
+
* @group Circles
|
|
142
|
+
*/
|
|
143
|
+
function resolveCircleConfig(config, hidden = false) {
|
|
144
|
+
var _a, _b, _c, _d;
|
|
145
|
+
validateRadiusMeters(config.radiusMeters);
|
|
146
|
+
validateCoordinate(config.coordinate);
|
|
147
|
+
return {
|
|
148
|
+
id: (_a = config.id) !== null && _a !== void 0 ? _a : (0, utils_1.generateHexadecimalKey)(),
|
|
149
|
+
coordinate: config.coordinate,
|
|
150
|
+
radiusMeters: config.radiusMeters,
|
|
151
|
+
fillColor: (_b = config.fillColor) !== null && _b !== void 0 ? _b : exports.CIRCLE_DEFAULTS.fillColor,
|
|
152
|
+
fillOpacity: clampOpacity(config.fillOpacity, exports.CIRCLE_DEFAULTS.fillOpacity),
|
|
153
|
+
strokeColor: (_c = config.strokeColor) !== null && _c !== void 0 ? _c : exports.CIRCLE_DEFAULTS.strokeColor,
|
|
154
|
+
strokeWidth: (_d = config.strokeWidth) !== null && _d !== void 0 ? _d : exports.CIRCLE_DEFAULTS.strokeWidth,
|
|
155
|
+
strokeOpacity: clampOpacity(config.strokeOpacity, exports.CIRCLE_DEFAULTS.strokeOpacity),
|
|
156
|
+
floorId: config.floorId,
|
|
157
|
+
hidden,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
exports.resolveCircleConfig = resolveCircleConfig;
|
|
161
|
+
/**
|
|
162
|
+
* Builds a closed GeoJSON polygon ring approximating a geographic circle.
|
|
163
|
+
*
|
|
164
|
+
* The ring is computed with an equirectangular approximation: meters are
|
|
165
|
+
* converted to degrees independently per axis, with the longitude scale
|
|
166
|
+
* corrected by the cosine of the latitude. For the radii the SDK works with
|
|
167
|
+
* (tens to hundreds of meters) the metric error is negligible (≤1%) at any latitude
|
|
168
|
+
* where the projection is defined. At extreme polar latitudes, the approximation
|
|
169
|
+
* breaks down, so circles near poles (|lat| > 85°) should be used with caution.
|
|
170
|
+
*
|
|
171
|
+
* @param lng Longitude of the circle center in degrees.
|
|
172
|
+
* @param lat Latitude of the circle center in degrees.
|
|
173
|
+
* @param radiusMeters Radius of the circle in meters. Must be positive and finite.
|
|
174
|
+
* @param points Number of segments in the ring. Defaults to 64. Non-integer
|
|
175
|
+
* values are floored and the count is clamped to a minimum of 3,
|
|
176
|
+
* the smallest valid GeoJSON linear ring; non-finite values fall
|
|
177
|
+
* back to the default.
|
|
178
|
+
* @returns A closed ring of `[lng, lat]` positions (first equals last).
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```typescript
|
|
182
|
+
* import { circleRing } from '@mapvx/web-js';
|
|
183
|
+
*
|
|
184
|
+
* // Create a 150-meter radius circle ring
|
|
185
|
+
* const ring = circleRing(-74.0060, 40.7128, 150);
|
|
186
|
+
* const polygon = { type: "Polygon", coordinates: [ring] };
|
|
187
|
+
*
|
|
188
|
+
* // Custom segments (32 instead of 64) for lower resolution
|
|
189
|
+
* const coarseRing = circleRing(-74.0060, 40.7128, 150, 32);
|
|
190
|
+
* ```
|
|
191
|
+
*
|
|
192
|
+
* @note Equirectangular approximation is accurate for radii up to ~500 km and
|
|
193
|
+
* latitudes between approximately ±80°. Beyond these limits, visual
|
|
194
|
+
* distortion may occur near the poles.
|
|
195
|
+
* @note Generated rings do not account for geographic obstacles, walls, or
|
|
196
|
+
* buildings. For complex geofencing, consider server-side validation.
|
|
197
|
+
*
|
|
198
|
+
* @group Circles
|
|
199
|
+
*/
|
|
200
|
+
function circleRing(lng, lat, radiusMeters, points = 64) {
|
|
201
|
+
// A linear ring needs at least 3 distinct positions to be valid GeoJSON
|
|
202
|
+
const segments = Number.isFinite(points) ? Math.max(3, Math.floor(points)) : 64;
|
|
203
|
+
const ring = [];
|
|
204
|
+
const latRad = (lat * Math.PI) / 180;
|
|
205
|
+
const metersPerDegLat = 110574;
|
|
206
|
+
const metersPerDegLng = 111320 * Math.cos(latRad || 0.000001);
|
|
207
|
+
const latR = radiusMeters / metersPerDegLat;
|
|
208
|
+
const lngR = radiusMeters / (metersPerDegLng || 1);
|
|
209
|
+
for (let i = 0; i < segments; i += 1) {
|
|
210
|
+
const a = (i / segments) * Math.PI * 2;
|
|
211
|
+
ring.push([lng + lngR * Math.cos(a), lat + latR * Math.sin(a)]);
|
|
212
|
+
}
|
|
213
|
+
// Close the ring with an exact copy of the first position, as GeoJSON requires
|
|
214
|
+
ring.push([ring[0][0], ring[0][1]]);
|
|
215
|
+
return ring;
|
|
216
|
+
}
|
|
217
|
+
exports.circleRing = circleRing;
|
|
218
|
+
//# sourceMappingURL=circle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circle.js","sourceRoot":"","sources":["../../../../src/domain/models/circle.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.loadStyles = exports.MAPVX_DEFAULT_PRECONNECT_HOSTS = exports.injectPreconnects = exports.isMapVxRequestHostname = exports.OpeningHoursHelper = exports.loadCustomization = exports.MVXTransport = exports.UnitSystem = exports.TransportationMode = exports.AnnounceFormat = exports.MVXRouteStep = exports.MVXRouteLeg = exports.MVXRoute = exports.MVXPlace = exports.TextPosition = exports.Institution = exports.isBasicWithLogo = exports.isBasicWithIcon = exports.Banner = exports.createRouteAnimationIconDataUrl = exports.initializeSDK = exports.CountlyLogger = exports.FetchHttpClient = exports.DEFAULT_MAX_STORAGE_BYTES = exports.DEFAULT_CACHE_CONFIGS = exports.CacheManager = exports.PersistentCache = exports.LRUCache = void 0;
|
|
3
|
+
exports.loadStyles = exports.MAPVX_DEFAULT_PRECONNECT_HOSTS = exports.injectPreconnects = exports.isMapVxRequestHostname = exports.OpeningHoursHelper = exports.loadCustomization = exports.MVXTransport = exports.UnitSystem = exports.TransportationMode = exports.AnnounceFormat = exports.MVXRouteStep = exports.MVXRouteLeg = exports.MVXRoute = exports.MVXPlace = exports.TextPosition = exports.Institution = exports.isValidCircleConfig = exports.MAPVX_BRAND_COLOR = exports.CIRCLE_DEFAULTS = exports.circleRing = exports.isBasicWithLogo = exports.isBasicWithIcon = exports.Banner = exports.createRouteAnimationIconDataUrl = exports.initializeSDK = exports.CountlyLogger = exports.FetchHttpClient = exports.DEFAULT_MAX_STORAGE_BYTES = exports.DEFAULT_CACHE_CONFIGS = exports.CacheManager = exports.PersistentCache = exports.LRUCache = void 0;
|
|
4
4
|
// ─── Infrastructure: Cache ───────────────────────────────────────────────────
|
|
5
5
|
var LRUCache_1 = require("./infrastructure/cache/LRUCache");
|
|
6
6
|
Object.defineProperty(exports, "LRUCache", { enumerable: true, get: function () { return LRUCache_1.LRUCache; } });
|
|
@@ -30,6 +30,12 @@ Object.defineProperty(exports, "Banner", { enumerable: true, get: function () {
|
|
|
30
30
|
var categories_1 = require("./domain/models/categories");
|
|
31
31
|
Object.defineProperty(exports, "isBasicWithIcon", { enumerable: true, get: function () { return categories_1.isBasicWithIcon; } });
|
|
32
32
|
Object.defineProperty(exports, "isBasicWithLogo", { enumerable: true, get: function () { return categories_1.isBasicWithLogo; } });
|
|
33
|
+
// ─── Domain Models: Circle ───────────────────────────────────────────────────
|
|
34
|
+
var circle_1 = require("./domain/models/circle");
|
|
35
|
+
Object.defineProperty(exports, "circleRing", { enumerable: true, get: function () { return circle_1.circleRing; } });
|
|
36
|
+
Object.defineProperty(exports, "CIRCLE_DEFAULTS", { enumerable: true, get: function () { return circle_1.CIRCLE_DEFAULTS; } });
|
|
37
|
+
Object.defineProperty(exports, "MAPVX_BRAND_COLOR", { enumerable: true, get: function () { return circle_1.MAPVX_BRAND_COLOR; } });
|
|
38
|
+
Object.defineProperty(exports, "isValidCircleConfig", { enumerable: true, get: function () { return circle_1.isValidCircleConfig; } });
|
|
33
39
|
// ─── Domain Models: Institution ──────────────────────────────────────────────
|
|
34
40
|
var institution_1 = require("./domain/models/institution");
|
|
35
41
|
Object.defineProperty(exports, "Institution", { enumerable: true, get: function () { return institution_1.Institution; } });
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAKA,gFAAgF;AAChF,4DAA0D;AAAjD,oGAAA,QAAQ,OAAA;AACjB,0EAAwE;AAA/D,kHAAA,eAAe,OAAA;AACxB,oEAAkE;AAAzD,4GAAA,YAAY,OAAA;AAErB,kEAG2C;AAFzC,oHAAA,qBAAqB,OAAA;AACrB,wHAAA,yBAAyB,OAAA;AAG3B,gFAAgF;AAChF,yEAAuE;AAA9D,kHAAA,eAAe,OAAA;AAExB,gFAAgF;AAChF,wEAAsE;AAA7D,8GAAA,aAAa,OAAA;AAKtB,gFAAgF;AAChF,6BAAqC;AAA5B,oGAAA,aAAa,OAAA;AAatB,gFAAgF;AAChF,wCAAgE;AAAvD,wHAAA,+BAA+B,OAAA;AAGxC,gFAAgF;AAChF,iDAA+C;AAAtC,gGAAA,MAAM,OAAA;AAEf,gFAAgF;AAChF,yDAA6E;AAApE,6GAAA,eAAe,OAAA;AAAE,6GAAA,eAAe,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAKA,gFAAgF;AAChF,4DAA0D;AAAjD,oGAAA,QAAQ,OAAA;AACjB,0EAAwE;AAA/D,kHAAA,eAAe,OAAA;AACxB,oEAAkE;AAAzD,4GAAA,YAAY,OAAA;AAErB,kEAG2C;AAFzC,oHAAA,qBAAqB,OAAA;AACrB,wHAAA,yBAAyB,OAAA;AAG3B,gFAAgF;AAChF,yEAAuE;AAA9D,kHAAA,eAAe,OAAA;AAExB,gFAAgF;AAChF,wEAAsE;AAA7D,8GAAA,aAAa,OAAA;AAKtB,gFAAgF;AAChF,6BAAqC;AAA5B,oGAAA,aAAa,OAAA;AAatB,gFAAgF;AAChF,wCAAgE;AAAvD,wHAAA,+BAA+B,OAAA;AAGxC,gFAAgF;AAChF,iDAA+C;AAAtC,gGAAA,MAAM,OAAA;AAEf,gFAAgF;AAChF,yDAA6E;AAApE,6GAAA,eAAe,OAAA;AAAE,6GAAA,eAAe,OAAA;AAezC,gFAAgF;AAChF,iDAK+B;AAJ7B,oGAAA,UAAU,OAAA;AACV,yGAAA,eAAe,OAAA;AACf,2GAAA,iBAAiB,OAAA;AACjB,6GAAA,mBAAmB,OAAA;AAqCrB,gFAAgF;AAChF,2DAAyD;AAAhD,0GAAA,WAAW,OAAA;AAYpB,gFAAgF;AAChF,iDAAqD;AAA5C,sGAAA,YAAY,OAAA;AASrB,gFAAgF;AAChF,+CAAgD;AAAvC,iGAAA,QAAQ,OAAA;AAKjB,gFAAgF;AAChF,+CAA2E;AAAlE,iGAAA,QAAQ,OAAA;AAAE,oGAAA,WAAW,OAAA;AAAE,qGAAA,YAAY,OAAA;AAE5C,gFAAgF;AAChF,yEAAmG;AAA1F,oHAAA,cAAc,OAAA;AAAE,wHAAA,kBAAkB,OAAA;AAAE,gHAAA,UAAU,OAAA;AAWvD,gFAAgF;AAChF,uDAAwD;AAA/C,yGAAA,YAAY,OAAA;AAQrB,gFAAgF;AAChF,iDAAsD;AAA7C,+GAAA,iBAAiB,OAAA;AAC1B,qEAAiE;AAAxD,0HAAA,kBAAkB,OAAA;AAC3B,uDAA8D;AAArD,uHAAA,sBAAsB,OAAA;AAC/B,iDAAsF;AAA7E,+GAAA,iBAAiB,OAAA;AAAE,4HAAA,8BAA8B,OAAA;AAE1D;;;GAGG;AACI,MAAM,UAAU,GAAG,GAAS,EAAE;IACnC,qCAAqC;IACrC,IAAI,QAAQ,CAAC,aAAa,CAAC,yBAAyB,CAAC,EAAE;QACrD,OAAM;KACP;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAA;IAC3C,IAAI,CAAC,GAAG,GAAG,YAAY,CAAA;IACvB,IAAI,CAAC,IAAI,GAAG,cAAc,CAAA,CAAC,wBAAwB;IACnD,IAAI,CAAC,YAAY,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAA;IAC9C,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;AACjC,CAAC,CAAA;AAXY,QAAA,UAAU,cAWtB"}
|
|
@@ -17,7 +17,7 @@ const countly = {
|
|
|
17
17
|
// The typeof guards make the lookup safe everywhere; the version placeholder
|
|
18
18
|
// is replaced with the package version by scripts/inject-build-defines.js.
|
|
19
19
|
const IS_DEBUG = typeof DEBUG !== "undefined" ? DEBUG : false;
|
|
20
|
-
const SDK_VERSION = typeof VERSION !== "undefined" ? VERSION : "1.
|
|
20
|
+
const SDK_VERSION = typeof VERSION !== "undefined" ? VERSION : "1.2.0";
|
|
21
21
|
class Logger {
|
|
22
22
|
constructor() {
|
|
23
23
|
var _a;
|
|
@@ -5,7 +5,7 @@ exports.argsToDict = exports._rollbarConfig = void 0;
|
|
|
5
5
|
// bundle. The tsc-built ES/CJS outputs keep it as a bare global, so the
|
|
6
6
|
// typeof guard makes the lookup safe everywhere; the version placeholder is
|
|
7
7
|
// replaced with the package version by scripts/inject-build-defines.js.
|
|
8
|
-
const SDK_VERSION = typeof VERSION !== "undefined" ? VERSION : "1.
|
|
8
|
+
const SDK_VERSION = typeof VERSION !== "undefined" ? VERSION : "1.2.0";
|
|
9
9
|
exports._rollbarConfig = {
|
|
10
10
|
accessToken: "28279d52df43411ebd138c2bee0ab1df",
|
|
11
11
|
// Only report what the SDK logs explicitly via logError. Capturing every
|
package/dist/cjs/map/map.js
CHANGED
|
@@ -25,6 +25,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.InternalMapVXMap = void 0;
|
|
27
27
|
const maplibre_gl_1 = __importStar(require("maplibre-gl"));
|
|
28
|
+
/** Shared GeoJSON source holding every circle drawn through the circle API. */
|
|
29
|
+
const CIRCLE_SOURCE_ID = "mapvx-circles";
|
|
30
|
+
/** Fill layer rendering the translucent interior of the circles. */
|
|
31
|
+
const CIRCLE_FILL_LAYER_ID = "mapvx-circles-fill";
|
|
32
|
+
/** Line layer rendering the circle outlines. */
|
|
33
|
+
const CIRCLE_LINE_LAYER_ID = "mapvx-circles-line";
|
|
28
34
|
// Flag to track if cached-tile protocol has been registered
|
|
29
35
|
let cachedTileProtocolRegistered = false;
|
|
30
36
|
/**
|
|
@@ -119,6 +125,7 @@ const _rtl_1 = require("../domain/models/_rtl");
|
|
|
119
125
|
const animation_1 = require("../domain/models/animation");
|
|
120
126
|
const loggeable_1 = require("../domain/models/loggeable");
|
|
121
127
|
const mapConfig_1 = require("../domain/models/mapConfig");
|
|
128
|
+
const circle_1 = require("../domain/models/circle");
|
|
122
129
|
const marker_1 = require("../domain/models/marker");
|
|
123
130
|
const route_1 = require("../domain/models/route");
|
|
124
131
|
const routeConfiguration_1 = require("../domain/models/routeConfiguration");
|
|
@@ -148,6 +155,7 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
148
155
|
this.currentFloor = "";
|
|
149
156
|
this.baseFilters = {};
|
|
150
157
|
this.markers = [];
|
|
158
|
+
this.circles = [];
|
|
151
159
|
this.enableHover = false;
|
|
152
160
|
this.hoveredId = "unselected";
|
|
153
161
|
this.failedTiles = new Set();
|
|
@@ -305,6 +313,12 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
305
313
|
this.onHover();
|
|
306
314
|
this.subscribeToFailedTiles();
|
|
307
315
|
});
|
|
316
|
+
// Self-healing for circles: a full style reload wipes custom sources and
|
|
317
|
+
// layers, and not every restyle path goes through whenStyleUpdates.
|
|
318
|
+
this.map.on("styledata", () => {
|
|
319
|
+
if (this.circles.length > 0)
|
|
320
|
+
this.ensureCircleLayers();
|
|
321
|
+
});
|
|
308
322
|
this.map.on("zoomend", () => {
|
|
309
323
|
var _a;
|
|
310
324
|
(_a = mapConfig.onZoomEnd) === null || _a === void 0 ? void 0 : _a.call(mapConfig, this.getZoomLevel());
|
|
@@ -423,6 +437,7 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
423
437
|
return Object.assign(Object.assign({}, segmentation), { token: this.token, parentPlaceId: (_a = this.parentPlaceId) !== null && _a !== void 0 ? _a : "None" });
|
|
424
438
|
}
|
|
425
439
|
destroyMap() {
|
|
440
|
+
this.circles = [];
|
|
426
441
|
this.map.remove();
|
|
427
442
|
this.unsubscribeFromFailedTiles();
|
|
428
443
|
}
|
|
@@ -526,6 +541,7 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
526
541
|
this.setBaseFilters(newStyle);
|
|
527
542
|
}
|
|
528
543
|
this.routeController.addSourcesAndLayers();
|
|
544
|
+
this.refreshCircles();
|
|
529
545
|
this.filterByFloorKey(this.currentFloor);
|
|
530
546
|
}
|
|
531
547
|
addMarker(marker) {
|
|
@@ -631,6 +647,260 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
631
647
|
throw new Error("Failed to remove all markers");
|
|
632
648
|
}
|
|
633
649
|
}
|
|
650
|
+
addCircle(circle) {
|
|
651
|
+
try {
|
|
652
|
+
// Check if a circle with the same ID already exists and replace it
|
|
653
|
+
if (circle.id) {
|
|
654
|
+
this.circles = this.circles.filter((c) => c.id !== circle.id);
|
|
655
|
+
}
|
|
656
|
+
// resolveCircleConfig validates radiusMeters and coordinates
|
|
657
|
+
const record = (0, circle_1.resolveCircleConfig)(circle);
|
|
658
|
+
this.circles.push(record);
|
|
659
|
+
this.refreshCircles();
|
|
660
|
+
this.logEvent("addCircle");
|
|
661
|
+
return record.id;
|
|
662
|
+
}
|
|
663
|
+
catch (error) {
|
|
664
|
+
throw new Error(`Failed to add circle: ${error instanceof Error ? error.message : String(error)}`);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
updateCircle(circleConfig) {
|
|
668
|
+
try {
|
|
669
|
+
const index = this.circles.findIndex((c) => c.id === circleConfig.id);
|
|
670
|
+
if (index === -1)
|
|
671
|
+
return null;
|
|
672
|
+
// resolveCircleConfig validates radiusMeters and coordinates
|
|
673
|
+
this.circles[index] = (0, circle_1.resolveCircleConfig)(circleConfig, this.circles[index].hidden);
|
|
674
|
+
this.refreshCircles();
|
|
675
|
+
this.logEvent("updateCircle");
|
|
676
|
+
return this.circles[index].id;
|
|
677
|
+
}
|
|
678
|
+
catch (error) {
|
|
679
|
+
throw new Error(`Failed to update circle: ${error instanceof Error ? error.message : String(error)}`);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
getCircle(circleId) {
|
|
683
|
+
return this.circles.find((c) => c.id === circleId);
|
|
684
|
+
}
|
|
685
|
+
getCircles() {
|
|
686
|
+
return this.circles.slice();
|
|
687
|
+
}
|
|
688
|
+
hasCircle(circleId) {
|
|
689
|
+
return this.circles.some((c) => c.id === circleId);
|
|
690
|
+
}
|
|
691
|
+
updateCirclePosition(circleId, center, radiusMeters) {
|
|
692
|
+
try {
|
|
693
|
+
const circle = this.circles.find((c) => c.id === circleId);
|
|
694
|
+
if (circle === undefined)
|
|
695
|
+
return false;
|
|
696
|
+
// Validate inputs before modifying
|
|
697
|
+
if (!center) {
|
|
698
|
+
throw new Error("Circle center is required");
|
|
699
|
+
}
|
|
700
|
+
const { lat, lng } = center;
|
|
701
|
+
if (!Number.isFinite(lat) || lat < -90 || lat > 90) {
|
|
702
|
+
throw new Error(`Invalid latitude: ${lat}. Must be between -90 and 90.`);
|
|
703
|
+
}
|
|
704
|
+
if (!Number.isFinite(lng) || lng < -180 || lng > 180) {
|
|
705
|
+
throw new Error(`Invalid longitude: ${lng}. Must be between -180 and 180.`);
|
|
706
|
+
}
|
|
707
|
+
if (radiusMeters !== undefined) {
|
|
708
|
+
if (!Number.isFinite(radiusMeters) || radiusMeters <= 0) {
|
|
709
|
+
throw new Error(`Invalid radiusMeters: ${radiusMeters}. Must be a positive finite number.`);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
circle.coordinate = center;
|
|
713
|
+
if (radiusMeters !== undefined) {
|
|
714
|
+
circle.radiusMeters = radiusMeters;
|
|
715
|
+
}
|
|
716
|
+
this.refreshCircles();
|
|
717
|
+
this.logEvent("updateCirclePosition");
|
|
718
|
+
return true;
|
|
719
|
+
}
|
|
720
|
+
catch (error) {
|
|
721
|
+
throw new Error(`Failed to update circle position: ${error instanceof Error ? error.message : String(error)}`);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
updateCircleStyle(circleId, style) {
|
|
725
|
+
try {
|
|
726
|
+
const circle = this.circles.find((c) => c.id === circleId);
|
|
727
|
+
if (circle === undefined)
|
|
728
|
+
return false;
|
|
729
|
+
// Update only style properties, clamp opacities
|
|
730
|
+
if (style.fillColor !== undefined)
|
|
731
|
+
circle.fillColor = style.fillColor;
|
|
732
|
+
if (style.fillOpacity !== undefined)
|
|
733
|
+
circle.fillOpacity = Math.max(0, Math.min(1, style.fillOpacity));
|
|
734
|
+
if (style.strokeColor !== undefined)
|
|
735
|
+
circle.strokeColor = style.strokeColor;
|
|
736
|
+
if (style.strokeWidth !== undefined)
|
|
737
|
+
circle.strokeWidth = style.strokeWidth;
|
|
738
|
+
if (style.strokeOpacity !== undefined)
|
|
739
|
+
circle.strokeOpacity = Math.max(0, Math.min(1, style.strokeOpacity));
|
|
740
|
+
this.refreshCircles();
|
|
741
|
+
this.logEvent("updateCircleStyle");
|
|
742
|
+
return true;
|
|
743
|
+
}
|
|
744
|
+
catch (error) {
|
|
745
|
+
throw new Error(`Failed to update circle style: ${error instanceof Error ? error.message : String(error)}`);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
removeCircle(circleId) {
|
|
749
|
+
try {
|
|
750
|
+
this.circles = this.circles.filter((c) => c.id !== circleId);
|
|
751
|
+
this.refreshCircles();
|
|
752
|
+
this.logEvent("removeCircle");
|
|
753
|
+
}
|
|
754
|
+
catch (error) {
|
|
755
|
+
throw new Error("Failed to remove circle");
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
removeAllCircles() {
|
|
759
|
+
try {
|
|
760
|
+
this.circles = [];
|
|
761
|
+
this.refreshCircles();
|
|
762
|
+
this.logEvent("removeAllCircles");
|
|
763
|
+
}
|
|
764
|
+
catch (error) {
|
|
765
|
+
throw new Error("Failed to remove all circles");
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
showCircle(circleId) {
|
|
769
|
+
try {
|
|
770
|
+
const circle = this.circles.find((c) => c.id === circleId);
|
|
771
|
+
if (circle === undefined) {
|
|
772
|
+
return false;
|
|
773
|
+
}
|
|
774
|
+
circle.hidden = false;
|
|
775
|
+
this.refreshCircles();
|
|
776
|
+
this.logEvent("showCircle");
|
|
777
|
+
return true;
|
|
778
|
+
}
|
|
779
|
+
catch (error) {
|
|
780
|
+
return false;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
hideCircle(circleId) {
|
|
784
|
+
try {
|
|
785
|
+
const circle = this.circles.find((c) => c.id === circleId);
|
|
786
|
+
if (circle === undefined) {
|
|
787
|
+
return false;
|
|
788
|
+
}
|
|
789
|
+
circle.hidden = true;
|
|
790
|
+
this.refreshCircles();
|
|
791
|
+
this.logEvent("hideCircle");
|
|
792
|
+
return true;
|
|
793
|
+
}
|
|
794
|
+
catch (error) {
|
|
795
|
+
return false;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
/**
|
|
799
|
+
* Builds the GeoJSON FeatureCollection for every currently visible circle.
|
|
800
|
+
* Visibility mirrors marker semantics: a circle with a floor is shown only
|
|
801
|
+
* while that floor is displayed, and a circle without a floor is shown only
|
|
802
|
+
* in outdoor contexts. Hidden circles are always omitted.
|
|
803
|
+
*/
|
|
804
|
+
circleFeatureCollection() {
|
|
805
|
+
var _a, _b, _c;
|
|
806
|
+
const floorId = (_a = this.currentFloor) !== null && _a !== void 0 ? _a : "";
|
|
807
|
+
const isOutdoor = !this.parentPlace ||
|
|
808
|
+
((_c = (_b = this.innerFloors.find((floor) => floor.key === floorId)) === null || _b === void 0 ? void 0 : _b.reachableFromGPS) !== null && _c !== void 0 ? _c : false);
|
|
809
|
+
const features = this.circles
|
|
810
|
+
.filter((circle) => {
|
|
811
|
+
var _a;
|
|
812
|
+
if (circle.hidden)
|
|
813
|
+
return false;
|
|
814
|
+
const circleFloor = (_a = circle.floorId) !== null && _a !== void 0 ? _a : "";
|
|
815
|
+
return circleFloor === floorId || (isOutdoor && circleFloor === "");
|
|
816
|
+
})
|
|
817
|
+
.map((circle) => ({
|
|
818
|
+
type: "Feature",
|
|
819
|
+
properties: {
|
|
820
|
+
id: circle.id,
|
|
821
|
+
fillColor: circle.fillColor,
|
|
822
|
+
fillOpacity: circle.fillOpacity,
|
|
823
|
+
strokeColor: circle.strokeColor,
|
|
824
|
+
strokeWidth: circle.strokeWidth,
|
|
825
|
+
strokeOpacity: circle.strokeOpacity,
|
|
826
|
+
},
|
|
827
|
+
geometry: {
|
|
828
|
+
type: "Polygon",
|
|
829
|
+
coordinates: [
|
|
830
|
+
(0, circle_1.circleRing)(circle.coordinate.lng, circle.coordinate.lat, circle.radiusMeters),
|
|
831
|
+
],
|
|
832
|
+
},
|
|
833
|
+
}));
|
|
834
|
+
return { type: "FeatureCollection", features };
|
|
835
|
+
}
|
|
836
|
+
/**
|
|
837
|
+
* Idempotently adds the shared circle source and its fill/line layers.
|
|
838
|
+
* Layers are inserted below the first symbol layer so place labels and
|
|
839
|
+
* markers stay readable above the translucent fill. Safe to call at any
|
|
840
|
+
* time: a style that is still loading simply rejects the calls, and the
|
|
841
|
+
* styledata listener retries once the style is ready.
|
|
842
|
+
*/
|
|
843
|
+
ensureCircleLayers() {
|
|
844
|
+
var _a, _b, _c;
|
|
845
|
+
if (!this.map)
|
|
846
|
+
return;
|
|
847
|
+
try {
|
|
848
|
+
if (!this.map.getSource(CIRCLE_SOURCE_ID)) {
|
|
849
|
+
this.map.addSource(CIRCLE_SOURCE_ID, {
|
|
850
|
+
type: "geojson",
|
|
851
|
+
data: this.circleFeatureCollection(),
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
const beforeId = (_c = (_b = (_a = this.map.getStyle()) === null || _a === void 0 ? void 0 : _a.layers) === null || _b === void 0 ? void 0 : _b.find((layer) => layer.type === "symbol")) === null || _c === void 0 ? void 0 : _c.id;
|
|
855
|
+
if (!this.map.getLayer(CIRCLE_FILL_LAYER_ID)) {
|
|
856
|
+
const fillLayer = {
|
|
857
|
+
id: CIRCLE_FILL_LAYER_ID,
|
|
858
|
+
type: "fill",
|
|
859
|
+
source: CIRCLE_SOURCE_ID,
|
|
860
|
+
paint: {
|
|
861
|
+
"fill-color": ["get", "fillColor"],
|
|
862
|
+
"fill-opacity": ["get", "fillOpacity"],
|
|
863
|
+
},
|
|
864
|
+
};
|
|
865
|
+
this.map.addLayer(fillLayer, beforeId);
|
|
866
|
+
}
|
|
867
|
+
if (!this.map.getLayer(CIRCLE_LINE_LAYER_ID)) {
|
|
868
|
+
const lineLayer = {
|
|
869
|
+
id: CIRCLE_LINE_LAYER_ID,
|
|
870
|
+
type: "line",
|
|
871
|
+
source: CIRCLE_SOURCE_ID,
|
|
872
|
+
paint: {
|
|
873
|
+
"line-color": ["get", "strokeColor"],
|
|
874
|
+
"line-width": ["get", "strokeWidth"],
|
|
875
|
+
"line-opacity": ["get", "strokeOpacity"],
|
|
876
|
+
},
|
|
877
|
+
};
|
|
878
|
+
this.map.addLayer(lineLayer, beforeId);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
catch (error) {
|
|
882
|
+
// Style may not be loaded yet; the styledata listener re-adds the layers
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* Re-renders all circles: ensures the source and layers exist, then pushes
|
|
887
|
+
* the current FeatureCollection. Called after every mutation of the circle
|
|
888
|
+
* list, on floor changes, and when the map style reloads.
|
|
889
|
+
*/
|
|
890
|
+
refreshCircles() {
|
|
891
|
+
if (!this.map)
|
|
892
|
+
return;
|
|
893
|
+
if (this.circles.length === 0 && !this.map.getSource(CIRCLE_SOURCE_ID))
|
|
894
|
+
return;
|
|
895
|
+
this.ensureCircleLayers();
|
|
896
|
+
try {
|
|
897
|
+
const source = this.map.getSource(CIRCLE_SOURCE_ID);
|
|
898
|
+
source === null || source === void 0 ? void 0 : source.setData(this.circleFeatureCollection());
|
|
899
|
+
}
|
|
900
|
+
catch (error) {
|
|
901
|
+
// Source may not exist while a new style is loading
|
|
902
|
+
}
|
|
903
|
+
}
|
|
634
904
|
/**
|
|
635
905
|
* Use it to change the current layer
|
|
636
906
|
* @param floorKey floor id
|
|
@@ -643,6 +913,7 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
643
913
|
}
|
|
644
914
|
this.updateFiltersTo(floorKeyString);
|
|
645
915
|
this.updateMarkersTo(floorKeyString);
|
|
916
|
+
this.refreshCircles();
|
|
646
917
|
this.routeController.updateRouteLayers(floorKeyString);
|
|
647
918
|
this.routeController.updateRouteMarkerVisibility(floorKeyString);
|
|
648
919
|
}
|
|
@@ -1045,7 +1316,7 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
1045
1316
|
filter: ["all", ["has", "ref"], ["==", ["get", "ref"], "unselected"]],
|
|
1046
1317
|
paint: {
|
|
1047
1318
|
"fill-extrusion-height": 2.5,
|
|
1048
|
-
"fill-extrusion-color":
|
|
1319
|
+
"fill-extrusion-color": circle_1.MAPVX_BRAND_COLOR,
|
|
1049
1320
|
"fill-extrusion-opacity": 0.8,
|
|
1050
1321
|
},
|
|
1051
1322
|
};
|
|
@@ -1059,7 +1330,7 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
1059
1330
|
"source-layer": "area",
|
|
1060
1331
|
filter: ["all", ["has", "ref"], ["==", ["get", "ref"], "unselected"]],
|
|
1061
1332
|
paint: {
|
|
1062
|
-
"fill-color":
|
|
1333
|
+
"fill-color": circle_1.MAPVX_BRAND_COLOR,
|
|
1063
1334
|
},
|
|
1064
1335
|
};
|
|
1065
1336
|
this.map.addLayer(layer);
|
|
@@ -1317,7 +1588,7 @@ class InternalMapVXMap extends loggeable_1.Loggeable {
|
|
|
1317
1588
|
"source-layer": "area",
|
|
1318
1589
|
filter: ["all", ["has", "ref"], ["==", ["get", "ref"], "unselected"]],
|
|
1319
1590
|
paint: {
|
|
1320
|
-
"line-color":
|
|
1591
|
+
"line-color": circle_1.MAPVX_BRAND_COLOR,
|
|
1321
1592
|
"line-width": 4,
|
|
1322
1593
|
},
|
|
1323
1594
|
};
|