@mapvx/web-js 1.1.0 → 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/domain/models/marker.js +6 -0
- package/dist/cjs/domain/models/marker.js.map +1 -1
- package/dist/cjs/index.js +10 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/logger/logger.js +15 -8
- package/dist/cjs/logger/logger.js.map +1 -1
- package/dist/cjs/logger/rollbar.js +16 -8
- package/dist/cjs/logger/rollbar.js.map +1 -1
- package/dist/cjs/map/map.js +274 -3
- package/dist/cjs/map/map.js.map +1 -1
- package/dist/cjs/utils/preconnect.js +131 -0
- package/dist/cjs/utils/preconnect.js.map +1 -0
- 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/domain/models/marker.d.ts +8 -0
- package/dist/es/domain/models/marker.d.ts.map +1 -1
- package/dist/es/domain/models/marker.js +6 -0
- package/dist/es/domain/models/marker.js.map +1 -1
- package/dist/es/index.d.ts +3 -0
- package/dist/es/index.d.ts.map +1 -1
- package/dist/es/index.js +3 -0
- package/dist/es/index.js.map +1 -1
- package/dist/es/logger/logger.d.ts.map +1 -1
- package/dist/es/logger/logger.js +15 -8
- package/dist/es/logger/logger.js.map +1 -1
- package/dist/es/logger/rollbar.d.ts.map +1 -1
- package/dist/es/logger/rollbar.js +16 -8
- package/dist/es/logger/rollbar.js.map +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/es/utils/preconnect.d.ts +45 -0
- package/dist/es/utils/preconnect.d.ts.map +1 -0
- package/dist/es/utils/preconnect.js +127 -0
- package/dist/es/utils/preconnect.js.map +1 -0
- package/dist/umd/index.js +735 -36
- package/dist/umd/index.js.map +1 -1
- package/package.json +5 -5
package/dist/umd/index.js
CHANGED
|
@@ -5721,6 +5721,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
5721
5721
|
__webpack_require__.d(__webpack_exports__, {
|
|
5722
5722
|
AnnounceFormat: () => (/* reexport */ AnnounceFormat),
|
|
5723
5723
|
Banner: () => (/* reexport */ Banner),
|
|
5724
|
+
CIRCLE_DEFAULTS: () => (/* reexport */ CIRCLE_DEFAULTS),
|
|
5724
5725
|
CacheManager: () => (/* reexport */ CacheManager),
|
|
5725
5726
|
CountlyLogger: () => (/* reexport */ CountlyLogger),
|
|
5726
5727
|
DEFAULT_CACHE_CONFIGS: () => (/* reexport */ DEFAULT_CACHE_CONFIGS),
|
|
@@ -5728,6 +5729,8 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
5728
5729
|
FetchHttpClient: () => (/* reexport */ FetchHttpClient),
|
|
5729
5730
|
Institution: () => (/* reexport */ Institution),
|
|
5730
5731
|
LRUCache: () => (/* reexport */ LRUCache),
|
|
5732
|
+
MAPVX_BRAND_COLOR: () => (/* reexport */ MAPVX_BRAND_COLOR),
|
|
5733
|
+
MAPVX_DEFAULT_PRECONNECT_HOSTS: () => (/* reexport */ MAPVX_DEFAULT_PRECONNECT_HOSTS),
|
|
5731
5734
|
MVXPlace: () => (/* reexport */ place_MVXPlace),
|
|
5732
5735
|
MVXRoute: () => (/* reexport */ MVXRoute),
|
|
5733
5736
|
MVXRouteLeg: () => (/* reexport */ MVXRouteLeg),
|
|
@@ -5738,11 +5741,14 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
5738
5741
|
TextPosition: () => (/* reexport */ TextPosition),
|
|
5739
5742
|
TransportationMode: () => (/* reexport */ TransportationMode),
|
|
5740
5743
|
UnitSystem: () => (/* reexport */ UnitSystem),
|
|
5744
|
+
circleRing: () => (/* reexport */ circleRing),
|
|
5741
5745
|
createRouteAnimationIconDataUrl: () => (/* reexport */ createRouteAnimationIconDataUrl),
|
|
5742
5746
|
initializeSDK: () => (/* reexport */ initializeSDK),
|
|
5747
|
+
injectPreconnects: () => (/* reexport */ injectPreconnects),
|
|
5743
5748
|
isBasicWithIcon: () => (/* reexport */ isBasicWithIcon),
|
|
5744
5749
|
isBasicWithLogo: () => (/* reexport */ isBasicWithLogo),
|
|
5745
5750
|
isMapVxRequestHostname: () => (/* reexport */ isMapVxRequestHostname),
|
|
5751
|
+
isValidCircleConfig: () => (/* reexport */ isValidCircleConfig),
|
|
5746
5752
|
loadCustomization: () => (/* reexport */ loadCustomization),
|
|
5747
5753
|
loadStyles: () => (/* binding */ loadStyles)
|
|
5748
5754
|
});
|
|
@@ -6784,18 +6790,26 @@ var countly_default = /*#__PURE__*/__webpack_require__.n(countly);
|
|
|
6784
6790
|
var rollbar_umd_min = __webpack_require__(916);
|
|
6785
6791
|
var rollbar_umd_min_default = /*#__PURE__*/__webpack_require__.n(rollbar_umd_min);
|
|
6786
6792
|
;// ./src/logger/rollbar.ts
|
|
6793
|
+
// VERSION is a webpack DefinePlugin constant, substituted only in the UMD
|
|
6794
|
+
// bundle. The tsc-built ES/CJS outputs keep it as a bare global, so the
|
|
6795
|
+
// typeof guard makes the lookup safe everywhere; the version placeholder is
|
|
6796
|
+
// replaced with the package version by scripts/inject-build-defines.js.
|
|
6797
|
+
var SDK_VERSION = true ? "1.2.0" : 0;
|
|
6787
6798
|
var _rollbarConfig = {
|
|
6788
|
-
accessToken: "
|
|
6789
|
-
|
|
6790
|
-
|
|
6799
|
+
accessToken: "28279d52df43411ebd138c2bee0ab1df",
|
|
6800
|
+
// Only report what the SDK logs explicitly via logError. Capturing every
|
|
6801
|
+
// uncaught error / unhandled rejection on the host page floods Rollbar
|
|
6802
|
+
// with items from third-party code (e.g. Countly, the host app itself)
|
|
6803
|
+
// that the SDK does not own.
|
|
6804
|
+
captureUncaught: false,
|
|
6805
|
+
captureUnhandledRejections: false,
|
|
6806
|
+
// Drop anything below error level (debug/info/warning).
|
|
6807
|
+
reportLevel: "error",
|
|
6791
6808
|
payload: {
|
|
6792
|
-
environment: "
|
|
6793
|
-
// context: 'rollbar/test'
|
|
6809
|
+
environment: "production",
|
|
6794
6810
|
client: {
|
|
6795
6811
|
javascript: {
|
|
6796
|
-
code_version:
|
|
6797
|
-
// source_map_enabled: true,
|
|
6798
|
-
// guess_uncaught_frames: true
|
|
6812
|
+
code_version: SDK_VERSION
|
|
6799
6813
|
}
|
|
6800
6814
|
}
|
|
6801
6815
|
}
|
|
@@ -6822,19 +6836,30 @@ var logger_countly = {
|
|
|
6822
6836
|
apiKey: "f0c8d3b96d336e857a8628f49dd1baf7d7add0e9",
|
|
6823
6837
|
url: "https://countly.lazarillo.app"
|
|
6824
6838
|
};
|
|
6839
|
+
// DEBUG and VERSION are webpack DefinePlugin constants, substituted only in
|
|
6840
|
+
// the UMD bundle. The tsc-built ES/CJS outputs keep them as bare globals, so
|
|
6841
|
+
// reading them directly throws ReferenceError in consumers of those builds.
|
|
6842
|
+
// The typeof guards make the lookup safe everywhere; the version placeholder
|
|
6843
|
+
// is replaced with the package version by scripts/inject-build-defines.js.
|
|
6844
|
+
var IS_DEBUG = true ? false : 0;
|
|
6845
|
+
var logger_SDK_VERSION = true ? "1.2.0" : 0;
|
|
6825
6846
|
var Logger = /*#__PURE__*/function () {
|
|
6826
6847
|
function Logger() {
|
|
6827
6848
|
logger_classCallCheck(this, Logger);
|
|
6828
|
-
if (
|
|
6829
|
-
|
|
6849
|
+
if (IS_DEBUG) {
|
|
6850
|
+
console.log("Initializing Countly");
|
|
6851
|
+
this.countly = {
|
|
6852
|
+
q: []
|
|
6853
|
+
};
|
|
6854
|
+
} else {
|
|
6830
6855
|
var _Countly$q;
|
|
6831
6856
|
this.rollbar = new (rollbar_umd_min_default())(_rollbarConfig);
|
|
6832
6857
|
countly_default().init({
|
|
6833
6858
|
app_key: logger_countly.apiKey,
|
|
6834
6859
|
url: logger_countly.url,
|
|
6835
|
-
app_version:
|
|
6860
|
+
app_version: logger_SDK_VERSION,
|
|
6836
6861
|
session_update: 10,
|
|
6837
|
-
debug:
|
|
6862
|
+
debug: IS_DEBUG,
|
|
6838
6863
|
require_consent: false,
|
|
6839
6864
|
namespace: "SDK JS"
|
|
6840
6865
|
});
|
|
@@ -6846,8 +6871,9 @@ var Logger = /*#__PURE__*/function () {
|
|
|
6846
6871
|
return logger_createClass(Logger, [{
|
|
6847
6872
|
key: "logEvent",
|
|
6848
6873
|
value: function logEvent(eventName, eventSegmentation) {
|
|
6849
|
-
if (
|
|
6850
|
-
|
|
6874
|
+
if (IS_DEBUG) {
|
|
6875
|
+
console.log(eventName, eventSegmentation);
|
|
6876
|
+
} else {
|
|
6851
6877
|
this.countly.q.push(["add_event", {
|
|
6852
6878
|
key: eventName,
|
|
6853
6879
|
segmentation: eventSegmentation
|
|
@@ -6857,14 +6883,18 @@ var Logger = /*#__PURE__*/function () {
|
|
|
6857
6883
|
}, {
|
|
6858
6884
|
key: "logDebug",
|
|
6859
6885
|
value: function logDebug() {
|
|
6860
|
-
if (
|
|
6861
|
-
|
|
6886
|
+
if (IS_DEBUG) {
|
|
6887
|
+
var _console;
|
|
6888
|
+
(_console = console).log.apply(_console, arguments);
|
|
6889
|
+
}
|
|
6862
6890
|
}
|
|
6863
6891
|
}, {
|
|
6864
6892
|
key: "logWarning",
|
|
6865
6893
|
value: function logWarning() {
|
|
6866
|
-
if (
|
|
6867
|
-
|
|
6894
|
+
if (IS_DEBUG) {
|
|
6895
|
+
var _console2;
|
|
6896
|
+
(_console2 = console).warn.apply(_console2, arguments);
|
|
6897
|
+
}
|
|
6868
6898
|
}
|
|
6869
6899
|
}, {
|
|
6870
6900
|
key: "logError",
|
|
@@ -6872,8 +6902,10 @@ var Logger = /*#__PURE__*/function () {
|
|
|
6872
6902
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
6873
6903
|
args[_key] = arguments[_key];
|
|
6874
6904
|
}
|
|
6875
|
-
if (
|
|
6876
|
-
|
|
6905
|
+
if (IS_DEBUG) {
|
|
6906
|
+
var _console3;
|
|
6907
|
+
(_console3 = console).error.apply(_console3, args);
|
|
6908
|
+
} else {
|
|
6877
6909
|
var _this$rollbar;
|
|
6878
6910
|
(_this$rollbar = this.rollbar) === null || _this$rollbar === void 0 || _this$rollbar.error.apply(_this$rollbar, args);
|
|
6879
6911
|
}
|
|
@@ -6882,8 +6914,7 @@ var Logger = /*#__PURE__*/function () {
|
|
|
6882
6914
|
key: "debugLog",
|
|
6883
6915
|
value: function debugLog() {
|
|
6884
6916
|
var _console4;
|
|
6885
|
-
if (
|
|
6886
|
-
{}
|
|
6917
|
+
if (IS_DEBUG) (_console4 = console).log.apply(_console4, arguments);
|
|
6887
6918
|
}
|
|
6888
6919
|
}], [{
|
|
6889
6920
|
key: "getInstance",
|
|
@@ -7569,6 +7600,9 @@ var MarkerAttribute = /*#__PURE__*/function (_Marker) {
|
|
|
7569
7600
|
_this.setLngLat([markerConfig.coordinate.lng, markerConfig.coordinate.lat]);
|
|
7570
7601
|
_this.setRotationAlignment((_markerConfig$rotatio = markerConfig.rotationAlignment) !== null && _markerConfig$rotatio !== void 0 ? _markerConfig$rotatio : "viewport");
|
|
7571
7602
|
_this.setPitchAlignment("viewport");
|
|
7603
|
+
if (typeof markerConfig.rotation === "number") {
|
|
7604
|
+
_this.setRotation(markerConfig.rotation);
|
|
7605
|
+
}
|
|
7572
7606
|
_this.id = (_markerConfig$id = markerConfig.id) !== null && _markerConfig$id !== void 0 ? _markerConfig$id : generateHexadecimalKey();
|
|
7573
7607
|
_this.coordinate = markerConfig.coordinate;
|
|
7574
7608
|
_this.floorId = (_markerConfig$floorId = markerConfig.floorId) !== null && _markerConfig$floorId !== void 0 ? _markerConfig$floorId : "";
|
|
@@ -7625,6 +7659,9 @@ var MarkerAttribute = /*#__PURE__*/function (_Marker) {
|
|
|
7625
7659
|
}
|
|
7626
7660
|
this.setRotationAlignment((_marker$rotationAlign = marker.rotationAlignment) !== null && _marker$rotationAlign !== void 0 ? _marker$rotationAlign : "viewport");
|
|
7627
7661
|
this.setPitchAlignment("viewport");
|
|
7662
|
+
if (typeof marker.rotation === "number") {
|
|
7663
|
+
this.setRotation(marker.rotation);
|
|
7664
|
+
}
|
|
7628
7665
|
}
|
|
7629
7666
|
|
|
7630
7667
|
/**
|
|
@@ -9591,6 +9628,230 @@ var DEFAULT_TILE_CACHE_CONFIG = {
|
|
|
9591
9628
|
* @property apiUrl - (Optional) Injected by SDK when creating map; base API URL for map requests.
|
|
9592
9629
|
* @property mapvxRequestContext - (Optional) Injected by SDK when creating map; context sent as headers to public-api.mapvx.com.
|
|
9593
9630
|
*/
|
|
9631
|
+
;// ./src/domain/models/circle.ts
|
|
9632
|
+
function circle_typeof(o) { "@babel/helpers - typeof"; return circle_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; }, circle_typeof(o); }
|
|
9633
|
+
|
|
9634
|
+
/**
|
|
9635
|
+
* MapVX brand color used as the default for circle styling and other
|
|
9636
|
+
* SDK-drawn overlays (colored places, borders).
|
|
9637
|
+
*
|
|
9638
|
+
* @group Circles
|
|
9639
|
+
*/
|
|
9640
|
+
var MAPVX_BRAND_COLOR = "#276EF1";
|
|
9641
|
+
|
|
9642
|
+
/**
|
|
9643
|
+
* Default styling values applied to a circle when the corresponding
|
|
9644
|
+
* {@link CircleConfig} fields are omitted.
|
|
9645
|
+
*
|
|
9646
|
+
* @group Circles
|
|
9647
|
+
*/
|
|
9648
|
+
var CIRCLE_DEFAULTS = {
|
|
9649
|
+
fillColor: MAPVX_BRAND_COLOR,
|
|
9650
|
+
fillOpacity: 0.14,
|
|
9651
|
+
strokeColor: MAPVX_BRAND_COLOR,
|
|
9652
|
+
strokeWidth: 2,
|
|
9653
|
+
strokeOpacity: 0.65
|
|
9654
|
+
};
|
|
9655
|
+
|
|
9656
|
+
/**
|
|
9657
|
+
* Represents the configuration for the creation of a metric radius circle on a map.
|
|
9658
|
+
* The radius is expressed in meters (geographic), so the drawn circle stays
|
|
9659
|
+
* metrically accurate at every zoom level.
|
|
9660
|
+
*
|
|
9661
|
+
* @example
|
|
9662
|
+
* ```typescript
|
|
9663
|
+
* const circleConfig: CircleConfig = {
|
|
9664
|
+
* id: "geofence-1",
|
|
9665
|
+
* coordinate: { lat: 40.7128, lng: -74.0060 },
|
|
9666
|
+
* radiusMeters: 150,
|
|
9667
|
+
* fillOpacity: 0.2,
|
|
9668
|
+
* };
|
|
9669
|
+
* ```
|
|
9670
|
+
*
|
|
9671
|
+
* @group Circles
|
|
9672
|
+
*/
|
|
9673
|
+
|
|
9674
|
+
/**
|
|
9675
|
+
* Internal resolved representation of a circle kept by the map.
|
|
9676
|
+
* Holds the full configuration with defaults applied, plus visibility state.
|
|
9677
|
+
*
|
|
9678
|
+
* Unlike markers, the hidden flag persists across floor changes and map
|
|
9679
|
+
* restyles: a circle hidden via `hideCircle` stays hidden until `showCircle`.
|
|
9680
|
+
*/
|
|
9681
|
+
|
|
9682
|
+
/**
|
|
9683
|
+
* Validates that a radius in meters is positive and finite.
|
|
9684
|
+
* @param radius The radius value to validate.
|
|
9685
|
+
* @throws {Error} If radius is ≤ 0 or not finite (NaN/Infinity).
|
|
9686
|
+
* @internal
|
|
9687
|
+
*/
|
|
9688
|
+
function validateRadiusMeters(radius) {
|
|
9689
|
+
if (!Number.isFinite(radius) || radius <= 0) {
|
|
9690
|
+
throw new Error("Invalid radiusMeters: ".concat(radius, ". Must be a positive finite number."));
|
|
9691
|
+
}
|
|
9692
|
+
}
|
|
9693
|
+
|
|
9694
|
+
/**
|
|
9695
|
+
* Validates that a coordinate is within valid geographic bounds.
|
|
9696
|
+
* @param coord The coordinate to validate.
|
|
9697
|
+
* @throws {Error} If latitude is outside [-90, 90] or longitude outside [-180, 180], or not finite.
|
|
9698
|
+
* @internal
|
|
9699
|
+
*/
|
|
9700
|
+
function validateCoordinate(coord) {
|
|
9701
|
+
if (coord == null || circle_typeof(coord) !== "object") {
|
|
9702
|
+
throw new Error("Invalid coordinate: expected an object with lat and lng properties.");
|
|
9703
|
+
}
|
|
9704
|
+
if (!Number.isFinite(coord.lat) || !Number.isFinite(coord.lng) || coord.lat < -90 || coord.lat > 90 || coord.lng < -180 || coord.lng > 180) {
|
|
9705
|
+
throw new Error("Invalid coordinate: lat=".concat(coord.lat, ", lng=").concat(coord.lng, ". ") + "latitude must be in [-90, 90], longitude in [-180, 180], and both finite.");
|
|
9706
|
+
}
|
|
9707
|
+
}
|
|
9708
|
+
|
|
9709
|
+
/**
|
|
9710
|
+
* Clamps an opacity value to the valid range [0, 1].
|
|
9711
|
+
* @param opacity The opacity value to clamp.
|
|
9712
|
+
* @param defaultValue Value to use if opacity is not a finite number.
|
|
9713
|
+
* @returns The clamped opacity value.
|
|
9714
|
+
* @internal
|
|
9715
|
+
*/
|
|
9716
|
+
function clampOpacity(opacity, defaultValue) {
|
|
9717
|
+
if (!Number.isFinite(opacity)) return defaultValue;
|
|
9718
|
+
return Math.max(0, Math.min(1, opacity));
|
|
9719
|
+
}
|
|
9720
|
+
|
|
9721
|
+
/**
|
|
9722
|
+
* Type guard for validating circle configurations without throwing.
|
|
9723
|
+
* Returns true if the configuration is valid and can be added to the map.
|
|
9724
|
+
*
|
|
9725
|
+
* @param config Configuration to validate.
|
|
9726
|
+
* @returns True if config is a valid CircleConfig, false otherwise.
|
|
9727
|
+
*
|
|
9728
|
+
* @example
|
|
9729
|
+
* ```typescript
|
|
9730
|
+
* if (isValidCircleConfig(userInput)) {
|
|
9731
|
+
* map.addCircle(userInput);
|
|
9732
|
+
* } else {
|
|
9733
|
+
* console.error('Invalid circle configuration');
|
|
9734
|
+
* }
|
|
9735
|
+
* ```
|
|
9736
|
+
*
|
|
9737
|
+
* @group Circles
|
|
9738
|
+
*/
|
|
9739
|
+
function isValidCircleConfig(config) {
|
|
9740
|
+
if (config === null || config === undefined || circle_typeof(config) !== "object") {
|
|
9741
|
+
return false;
|
|
9742
|
+
}
|
|
9743
|
+
var c = config;
|
|
9744
|
+
if (circle_typeof(c.coordinate) !== "object" || c.coordinate === null) return false;
|
|
9745
|
+
var coord = c.coordinate;
|
|
9746
|
+
if (typeof coord.lat !== "number" || typeof coord.lng !== "number" || !Number.isFinite(coord.lat) || !Number.isFinite(coord.lng) || coord.lat < -90 || coord.lat > 90 || coord.lng < -180 || coord.lng > 180) {
|
|
9747
|
+
return false;
|
|
9748
|
+
}
|
|
9749
|
+
if (typeof c.radiusMeters !== "number" || !Number.isFinite(c.radiusMeters) || c.radiusMeters <= 0) {
|
|
9750
|
+
return false;
|
|
9751
|
+
}
|
|
9752
|
+
if (c.id !== undefined && typeof c.id !== "string") return false;
|
|
9753
|
+
if (c.fillColor !== undefined && typeof c.fillColor !== "string") return false;
|
|
9754
|
+
if (c.fillOpacity !== undefined) {
|
|
9755
|
+
if (typeof c.fillOpacity !== "number" || !Number.isFinite(c.fillOpacity)) return false;
|
|
9756
|
+
}
|
|
9757
|
+
if (c.strokeColor !== undefined && typeof c.strokeColor !== "string") return false;
|
|
9758
|
+
if (c.strokeWidth !== undefined) {
|
|
9759
|
+
if (typeof c.strokeWidth !== "number" || !Number.isFinite(c.strokeWidth)) return false;
|
|
9760
|
+
}
|
|
9761
|
+
if (c.strokeOpacity !== undefined) {
|
|
9762
|
+
if (typeof c.strokeOpacity !== "number" || !Number.isFinite(c.strokeOpacity)) return false;
|
|
9763
|
+
}
|
|
9764
|
+
if (c.floorId !== undefined && typeof c.floorId !== "string") return false;
|
|
9765
|
+
return true;
|
|
9766
|
+
}
|
|
9767
|
+
|
|
9768
|
+
/**
|
|
9769
|
+
* Resolves a {@link CircleConfig} into a {@link CircleRecord}, applying
|
|
9770
|
+
* default styling, generating an id when one is not provided, and validating inputs.
|
|
9771
|
+
*
|
|
9772
|
+
* @param config Circle configuration provided by the SDK consumer.
|
|
9773
|
+
* @param hidden Initial hidden state, defaults to visible.
|
|
9774
|
+
* @returns The resolved circle record ready to be stored and rendered.
|
|
9775
|
+
* @throws {Error} If radiusMeters is ≤ 0, not finite, or coordinates are invalid.
|
|
9776
|
+
*
|
|
9777
|
+
* @group Circles
|
|
9778
|
+
*/
|
|
9779
|
+
function resolveCircleConfig(config) {
|
|
9780
|
+
var _config$id, _config$fillColor, _config$strokeColor, _config$strokeWidth;
|
|
9781
|
+
var hidden = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
9782
|
+
validateRadiusMeters(config.radiusMeters);
|
|
9783
|
+
validateCoordinate(config.coordinate);
|
|
9784
|
+
return {
|
|
9785
|
+
id: (_config$id = config.id) !== null && _config$id !== void 0 ? _config$id : generateHexadecimalKey(),
|
|
9786
|
+
coordinate: config.coordinate,
|
|
9787
|
+
radiusMeters: config.radiusMeters,
|
|
9788
|
+
fillColor: (_config$fillColor = config.fillColor) !== null && _config$fillColor !== void 0 ? _config$fillColor : CIRCLE_DEFAULTS.fillColor,
|
|
9789
|
+
fillOpacity: clampOpacity(config.fillOpacity, CIRCLE_DEFAULTS.fillOpacity),
|
|
9790
|
+
strokeColor: (_config$strokeColor = config.strokeColor) !== null && _config$strokeColor !== void 0 ? _config$strokeColor : CIRCLE_DEFAULTS.strokeColor,
|
|
9791
|
+
strokeWidth: (_config$strokeWidth = config.strokeWidth) !== null && _config$strokeWidth !== void 0 ? _config$strokeWidth : CIRCLE_DEFAULTS.strokeWidth,
|
|
9792
|
+
strokeOpacity: clampOpacity(config.strokeOpacity, CIRCLE_DEFAULTS.strokeOpacity),
|
|
9793
|
+
floorId: config.floorId,
|
|
9794
|
+
hidden: hidden
|
|
9795
|
+
};
|
|
9796
|
+
}
|
|
9797
|
+
|
|
9798
|
+
/**
|
|
9799
|
+
* Builds a closed GeoJSON polygon ring approximating a geographic circle.
|
|
9800
|
+
*
|
|
9801
|
+
* The ring is computed with an equirectangular approximation: meters are
|
|
9802
|
+
* converted to degrees independently per axis, with the longitude scale
|
|
9803
|
+
* corrected by the cosine of the latitude. For the radii the SDK works with
|
|
9804
|
+
* (tens to hundreds of meters) the metric error is negligible (≤1%) at any latitude
|
|
9805
|
+
* where the projection is defined. At extreme polar latitudes, the approximation
|
|
9806
|
+
* breaks down, so circles near poles (|lat| > 85°) should be used with caution.
|
|
9807
|
+
*
|
|
9808
|
+
* @param lng Longitude of the circle center in degrees.
|
|
9809
|
+
* @param lat Latitude of the circle center in degrees.
|
|
9810
|
+
* @param radiusMeters Radius of the circle in meters. Must be positive and finite.
|
|
9811
|
+
* @param points Number of segments in the ring. Defaults to 64. Non-integer
|
|
9812
|
+
* values are floored and the count is clamped to a minimum of 3,
|
|
9813
|
+
* the smallest valid GeoJSON linear ring; non-finite values fall
|
|
9814
|
+
* back to the default.
|
|
9815
|
+
* @returns A closed ring of `[lng, lat]` positions (first equals last).
|
|
9816
|
+
*
|
|
9817
|
+
* @example
|
|
9818
|
+
* ```typescript
|
|
9819
|
+
* import { circleRing } from '@mapvx/web-js';
|
|
9820
|
+
*
|
|
9821
|
+
* // Create a 150-meter radius circle ring
|
|
9822
|
+
* const ring = circleRing(-74.0060, 40.7128, 150);
|
|
9823
|
+
* const polygon = { type: "Polygon", coordinates: [ring] };
|
|
9824
|
+
*
|
|
9825
|
+
* // Custom segments (32 instead of 64) for lower resolution
|
|
9826
|
+
* const coarseRing = circleRing(-74.0060, 40.7128, 150, 32);
|
|
9827
|
+
* ```
|
|
9828
|
+
*
|
|
9829
|
+
* @note Equirectangular approximation is accurate for radii up to ~500 km and
|
|
9830
|
+
* latitudes between approximately ±80°. Beyond these limits, visual
|
|
9831
|
+
* distortion may occur near the poles.
|
|
9832
|
+
* @note Generated rings do not account for geographic obstacles, walls, or
|
|
9833
|
+
* buildings. For complex geofencing, consider server-side validation.
|
|
9834
|
+
*
|
|
9835
|
+
* @group Circles
|
|
9836
|
+
*/
|
|
9837
|
+
function circleRing(lng, lat, radiusMeters) {
|
|
9838
|
+
var points = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 64;
|
|
9839
|
+
// A linear ring needs at least 3 distinct positions to be valid GeoJSON
|
|
9840
|
+
var segments = Number.isFinite(points) ? Math.max(3, Math.floor(points)) : 64;
|
|
9841
|
+
var ring = [];
|
|
9842
|
+
var latRad = lat * Math.PI / 180;
|
|
9843
|
+
var metersPerDegLat = 110574;
|
|
9844
|
+
var metersPerDegLng = 111320 * Math.cos(latRad || 0.000001);
|
|
9845
|
+
var latR = radiusMeters / metersPerDegLat;
|
|
9846
|
+
var lngR = radiusMeters / (metersPerDegLng || 1);
|
|
9847
|
+
for (var i = 0; i < segments; i += 1) {
|
|
9848
|
+
var a = i / segments * Math.PI * 2;
|
|
9849
|
+
ring.push([lng + lngR * Math.cos(a), lat + latR * Math.sin(a)]);
|
|
9850
|
+
}
|
|
9851
|
+
// Close the ring with an exact copy of the first position, as GeoJSON requires
|
|
9852
|
+
ring.push([ring[0][0], ring[0][1]]);
|
|
9853
|
+
return ring;
|
|
9854
|
+
}
|
|
9594
9855
|
;// ./node_modules/.pnpm/@googlemaps+polyline-codec@1.0.28/node_modules/@googlemaps/polyline-codec/dist/index.esm.js
|
|
9595
9856
|
/**
|
|
9596
9857
|
* Copyright 2020 Google LLC
|
|
@@ -13180,6 +13441,12 @@ function map_defineProperty(e, r, t) { return (r = map_toPropertyKey(r)) in e ?
|
|
|
13180
13441
|
function map_toPropertyKey(t) { var i = map_toPrimitive(t, "string"); return "symbol" == map_typeof(i) ? i : i + ""; }
|
|
13181
13442
|
function map_toPrimitive(t, r) { if ("object" != map_typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != map_typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
13182
13443
|
|
|
13444
|
+
/** Shared GeoJSON source holding every circle drawn through the circle API. */
|
|
13445
|
+
var CIRCLE_SOURCE_ID = "mapvx-circles";
|
|
13446
|
+
/** Fill layer rendering the translucent interior of the circles. */
|
|
13447
|
+
var CIRCLE_FILL_LAYER_ID = "mapvx-circles-fill";
|
|
13448
|
+
/** Line layer rendering the circle outlines. */
|
|
13449
|
+
var CIRCLE_LINE_LAYER_ID = "mapvx-circles-line";
|
|
13183
13450
|
|
|
13184
13451
|
// Flag to track if cached-tile protocol has been registered
|
|
13185
13452
|
var cachedTileProtocolRegistered = false;
|
|
@@ -13294,6 +13561,7 @@ function convertPaddingToPixels(padding, containerWidth, containerHeight) {
|
|
|
13294
13561
|
|
|
13295
13562
|
|
|
13296
13563
|
|
|
13564
|
+
|
|
13297
13565
|
/**
|
|
13298
13566
|
* @group Map
|
|
13299
13567
|
*/
|
|
@@ -13323,6 +13591,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
13323
13591
|
map_defineProperty(_this, "currentFloor", "");
|
|
13324
13592
|
map_defineProperty(_this, "baseFilters", {});
|
|
13325
13593
|
map_defineProperty(_this, "markers", []);
|
|
13594
|
+
map_defineProperty(_this, "circles", []);
|
|
13326
13595
|
map_defineProperty(_this, "enableHover", false);
|
|
13327
13596
|
map_defineProperty(_this, "hoveredId", "unselected");
|
|
13328
13597
|
map_defineProperty(_this, "failedTiles", new Set());
|
|
@@ -13489,6 +13758,11 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
13489
13758
|
_this6.onHover();
|
|
13490
13759
|
_this6.subscribeToFailedTiles();
|
|
13491
13760
|
});
|
|
13761
|
+
// Self-healing for circles: a full style reload wipes custom sources and
|
|
13762
|
+
// layers, and not every restyle path goes through whenStyleUpdates.
|
|
13763
|
+
this.map.on("styledata", function () {
|
|
13764
|
+
if (_this6.circles.length > 0) _this6.ensureCircleLayers();
|
|
13765
|
+
});
|
|
13492
13766
|
this.map.on("zoomend", function () {
|
|
13493
13767
|
var _mapConfig$onZoomEnd;
|
|
13494
13768
|
(_mapConfig$onZoomEnd = mapConfig.onZoomEnd) === null || _mapConfig$onZoomEnd === void 0 || _mapConfig$onZoomEnd.call(mapConfig, _this6.getZoomLevel());
|
|
@@ -13586,6 +13860,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
13586
13860
|
}, {
|
|
13587
13861
|
key: "destroyMap",
|
|
13588
13862
|
value: function destroyMap() {
|
|
13863
|
+
this.circles = [];
|
|
13589
13864
|
this.map.remove();
|
|
13590
13865
|
this.unsubscribeFromFailedTiles();
|
|
13591
13866
|
}
|
|
@@ -13723,6 +13998,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
13723
13998
|
this.setBaseFilters(newStyle);
|
|
13724
13999
|
}
|
|
13725
14000
|
this.routeController.addSourcesAndLayers();
|
|
14001
|
+
this.refreshCircles();
|
|
13726
14002
|
this.filterByFloorKey(this.currentFloor);
|
|
13727
14003
|
}
|
|
13728
14004
|
}, {
|
|
@@ -13851,6 +14127,295 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
13851
14127
|
throw new Error("Failed to remove all markers");
|
|
13852
14128
|
}
|
|
13853
14129
|
}
|
|
14130
|
+
}, {
|
|
14131
|
+
key: "addCircle",
|
|
14132
|
+
value: function addCircle(circle) {
|
|
14133
|
+
try {
|
|
14134
|
+
// Check if a circle with the same ID already exists and replace it
|
|
14135
|
+
if (circle.id) {
|
|
14136
|
+
this.circles = this.circles.filter(function (c) {
|
|
14137
|
+
return c.id !== circle.id;
|
|
14138
|
+
});
|
|
14139
|
+
}
|
|
14140
|
+
// resolveCircleConfig validates radiusMeters and coordinates
|
|
14141
|
+
var record = resolveCircleConfig(circle);
|
|
14142
|
+
this.circles.push(record);
|
|
14143
|
+
this.refreshCircles();
|
|
14144
|
+
this.logEvent("addCircle");
|
|
14145
|
+
return record.id;
|
|
14146
|
+
} catch (error) {
|
|
14147
|
+
throw new Error("Failed to add circle: ".concat(error instanceof Error ? error.message : String(error)));
|
|
14148
|
+
}
|
|
14149
|
+
}
|
|
14150
|
+
}, {
|
|
14151
|
+
key: "updateCircle",
|
|
14152
|
+
value: function updateCircle(circleConfig) {
|
|
14153
|
+
try {
|
|
14154
|
+
var index = this.circles.findIndex(function (c) {
|
|
14155
|
+
return c.id === circleConfig.id;
|
|
14156
|
+
});
|
|
14157
|
+
if (index === -1) return null;
|
|
14158
|
+
|
|
14159
|
+
// resolveCircleConfig validates radiusMeters and coordinates
|
|
14160
|
+
this.circles[index] = resolveCircleConfig(circleConfig, this.circles[index].hidden);
|
|
14161
|
+
this.refreshCircles();
|
|
14162
|
+
this.logEvent("updateCircle");
|
|
14163
|
+
return this.circles[index].id;
|
|
14164
|
+
} catch (error) {
|
|
14165
|
+
throw new Error("Failed to update circle: ".concat(error instanceof Error ? error.message : String(error)));
|
|
14166
|
+
}
|
|
14167
|
+
}
|
|
14168
|
+
}, {
|
|
14169
|
+
key: "getCircle",
|
|
14170
|
+
value: function getCircle(circleId) {
|
|
14171
|
+
return this.circles.find(function (c) {
|
|
14172
|
+
return c.id === circleId;
|
|
14173
|
+
});
|
|
14174
|
+
}
|
|
14175
|
+
}, {
|
|
14176
|
+
key: "getCircles",
|
|
14177
|
+
value: function getCircles() {
|
|
14178
|
+
return this.circles.slice();
|
|
14179
|
+
}
|
|
14180
|
+
}, {
|
|
14181
|
+
key: "hasCircle",
|
|
14182
|
+
value: function hasCircle(circleId) {
|
|
14183
|
+
return this.circles.some(function (c) {
|
|
14184
|
+
return c.id === circleId;
|
|
14185
|
+
});
|
|
14186
|
+
}
|
|
14187
|
+
}, {
|
|
14188
|
+
key: "updateCirclePosition",
|
|
14189
|
+
value: function updateCirclePosition(circleId, center, radiusMeters) {
|
|
14190
|
+
try {
|
|
14191
|
+
var _circle = this.circles.find(function (c) {
|
|
14192
|
+
return c.id === circleId;
|
|
14193
|
+
});
|
|
14194
|
+
if (_circle === undefined) return false;
|
|
14195
|
+
|
|
14196
|
+
// Validate inputs before modifying
|
|
14197
|
+
if (!center) {
|
|
14198
|
+
throw new Error("Circle center is required");
|
|
14199
|
+
}
|
|
14200
|
+
var lat = center.lat,
|
|
14201
|
+
lng = center.lng;
|
|
14202
|
+
if (!Number.isFinite(lat) || lat < -90 || lat > 90) {
|
|
14203
|
+
throw new Error("Invalid latitude: ".concat(lat, ". Must be between -90 and 90."));
|
|
14204
|
+
}
|
|
14205
|
+
if (!Number.isFinite(lng) || lng < -180 || lng > 180) {
|
|
14206
|
+
throw new Error("Invalid longitude: ".concat(lng, ". Must be between -180 and 180."));
|
|
14207
|
+
}
|
|
14208
|
+
if (radiusMeters !== undefined) {
|
|
14209
|
+
if (!Number.isFinite(radiusMeters) || radiusMeters <= 0) {
|
|
14210
|
+
throw new Error("Invalid radiusMeters: ".concat(radiusMeters, ". Must be a positive finite number."));
|
|
14211
|
+
}
|
|
14212
|
+
}
|
|
14213
|
+
_circle.coordinate = center;
|
|
14214
|
+
if (radiusMeters !== undefined) {
|
|
14215
|
+
_circle.radiusMeters = radiusMeters;
|
|
14216
|
+
}
|
|
14217
|
+
this.refreshCircles();
|
|
14218
|
+
this.logEvent("updateCirclePosition");
|
|
14219
|
+
return true;
|
|
14220
|
+
} catch (error) {
|
|
14221
|
+
throw new Error("Failed to update circle position: ".concat(error instanceof Error ? error.message : String(error)));
|
|
14222
|
+
}
|
|
14223
|
+
}
|
|
14224
|
+
}, {
|
|
14225
|
+
key: "updateCircleStyle",
|
|
14226
|
+
value: function updateCircleStyle(circleId, style) {
|
|
14227
|
+
try {
|
|
14228
|
+
var _circle2 = this.circles.find(function (c) {
|
|
14229
|
+
return c.id === circleId;
|
|
14230
|
+
});
|
|
14231
|
+
if (_circle2 === undefined) return false;
|
|
14232
|
+
|
|
14233
|
+
// Update only style properties, clamp opacities
|
|
14234
|
+
if (style.fillColor !== undefined) _circle2.fillColor = style.fillColor;
|
|
14235
|
+
if (style.fillOpacity !== undefined) _circle2.fillOpacity = Math.max(0, Math.min(1, style.fillOpacity));
|
|
14236
|
+
if (style.strokeColor !== undefined) _circle2.strokeColor = style.strokeColor;
|
|
14237
|
+
if (style.strokeWidth !== undefined) _circle2.strokeWidth = style.strokeWidth;
|
|
14238
|
+
if (style.strokeOpacity !== undefined) _circle2.strokeOpacity = Math.max(0, Math.min(1, style.strokeOpacity));
|
|
14239
|
+
this.refreshCircles();
|
|
14240
|
+
this.logEvent("updateCircleStyle");
|
|
14241
|
+
return true;
|
|
14242
|
+
} catch (error) {
|
|
14243
|
+
throw new Error("Failed to update circle style: ".concat(error instanceof Error ? error.message : String(error)));
|
|
14244
|
+
}
|
|
14245
|
+
}
|
|
14246
|
+
}, {
|
|
14247
|
+
key: "removeCircle",
|
|
14248
|
+
value: function removeCircle(circleId) {
|
|
14249
|
+
try {
|
|
14250
|
+
this.circles = this.circles.filter(function (c) {
|
|
14251
|
+
return c.id !== circleId;
|
|
14252
|
+
});
|
|
14253
|
+
this.refreshCircles();
|
|
14254
|
+
this.logEvent("removeCircle");
|
|
14255
|
+
} catch (error) {
|
|
14256
|
+
throw new Error("Failed to remove circle");
|
|
14257
|
+
}
|
|
14258
|
+
}
|
|
14259
|
+
}, {
|
|
14260
|
+
key: "removeAllCircles",
|
|
14261
|
+
value: function removeAllCircles() {
|
|
14262
|
+
try {
|
|
14263
|
+
this.circles = [];
|
|
14264
|
+
this.refreshCircles();
|
|
14265
|
+
this.logEvent("removeAllCircles");
|
|
14266
|
+
} catch (error) {
|
|
14267
|
+
throw new Error("Failed to remove all circles");
|
|
14268
|
+
}
|
|
14269
|
+
}
|
|
14270
|
+
}, {
|
|
14271
|
+
key: "showCircle",
|
|
14272
|
+
value: function showCircle(circleId) {
|
|
14273
|
+
try {
|
|
14274
|
+
var _circle3 = this.circles.find(function (c) {
|
|
14275
|
+
return c.id === circleId;
|
|
14276
|
+
});
|
|
14277
|
+
if (_circle3 === undefined) {
|
|
14278
|
+
return false;
|
|
14279
|
+
}
|
|
14280
|
+
_circle3.hidden = false;
|
|
14281
|
+
this.refreshCircles();
|
|
14282
|
+
this.logEvent("showCircle");
|
|
14283
|
+
return true;
|
|
14284
|
+
} catch (error) {
|
|
14285
|
+
return false;
|
|
14286
|
+
}
|
|
14287
|
+
}
|
|
14288
|
+
}, {
|
|
14289
|
+
key: "hideCircle",
|
|
14290
|
+
value: function hideCircle(circleId) {
|
|
14291
|
+
try {
|
|
14292
|
+
var _circle4 = this.circles.find(function (c) {
|
|
14293
|
+
return c.id === circleId;
|
|
14294
|
+
});
|
|
14295
|
+
if (_circle4 === undefined) {
|
|
14296
|
+
return false;
|
|
14297
|
+
}
|
|
14298
|
+
_circle4.hidden = true;
|
|
14299
|
+
this.refreshCircles();
|
|
14300
|
+
this.logEvent("hideCircle");
|
|
14301
|
+
return true;
|
|
14302
|
+
} catch (error) {
|
|
14303
|
+
return false;
|
|
14304
|
+
}
|
|
14305
|
+
}
|
|
14306
|
+
|
|
14307
|
+
/**
|
|
14308
|
+
* Builds the GeoJSON FeatureCollection for every currently visible circle.
|
|
14309
|
+
* Visibility mirrors marker semantics: a circle with a floor is shown only
|
|
14310
|
+
* while that floor is displayed, and a circle without a floor is shown only
|
|
14311
|
+
* in outdoor contexts. Hidden circles are always omitted.
|
|
14312
|
+
*/
|
|
14313
|
+
}, {
|
|
14314
|
+
key: "circleFeatureCollection",
|
|
14315
|
+
value: function circleFeatureCollection() {
|
|
14316
|
+
var _this$currentFloor3, _this$innerFloors$fin6, _this$innerFloors$fin7;
|
|
14317
|
+
var floorId = (_this$currentFloor3 = this.currentFloor) !== null && _this$currentFloor3 !== void 0 ? _this$currentFloor3 : "";
|
|
14318
|
+
var isOutdoor = !this.parentPlace || ((_this$innerFloors$fin6 = (_this$innerFloors$fin7 = this.innerFloors.find(function (floor) {
|
|
14319
|
+
return floor.key === floorId;
|
|
14320
|
+
})) === null || _this$innerFloors$fin7 === void 0 ? void 0 : _this$innerFloors$fin7.reachableFromGPS) !== null && _this$innerFloors$fin6 !== void 0 ? _this$innerFloors$fin6 : false);
|
|
14321
|
+
var features = this.circles.filter(function (circle) {
|
|
14322
|
+
var _circle$floorId;
|
|
14323
|
+
if (circle.hidden) return false;
|
|
14324
|
+
var circleFloor = (_circle$floorId = circle.floorId) !== null && _circle$floorId !== void 0 ? _circle$floorId : "";
|
|
14325
|
+
return circleFloor === floorId || isOutdoor && circleFloor === "";
|
|
14326
|
+
}).map(function (circle) {
|
|
14327
|
+
return {
|
|
14328
|
+
type: "Feature",
|
|
14329
|
+
properties: {
|
|
14330
|
+
id: circle.id,
|
|
14331
|
+
fillColor: circle.fillColor,
|
|
14332
|
+
fillOpacity: circle.fillOpacity,
|
|
14333
|
+
strokeColor: circle.strokeColor,
|
|
14334
|
+
strokeWidth: circle.strokeWidth,
|
|
14335
|
+
strokeOpacity: circle.strokeOpacity
|
|
14336
|
+
},
|
|
14337
|
+
geometry: {
|
|
14338
|
+
type: "Polygon",
|
|
14339
|
+
coordinates: [circleRing(circle.coordinate.lng, circle.coordinate.lat, circle.radiusMeters)]
|
|
14340
|
+
}
|
|
14341
|
+
};
|
|
14342
|
+
});
|
|
14343
|
+
return {
|
|
14344
|
+
type: "FeatureCollection",
|
|
14345
|
+
features: features
|
|
14346
|
+
};
|
|
14347
|
+
}
|
|
14348
|
+
|
|
14349
|
+
/**
|
|
14350
|
+
* Idempotently adds the shared circle source and its fill/line layers.
|
|
14351
|
+
* Layers are inserted below the first symbol layer so place labels and
|
|
14352
|
+
* markers stay readable above the translucent fill. Safe to call at any
|
|
14353
|
+
* time: a style that is still loading simply rejects the calls, and the
|
|
14354
|
+
* styledata listener retries once the style is ready.
|
|
14355
|
+
*/
|
|
14356
|
+
}, {
|
|
14357
|
+
key: "ensureCircleLayers",
|
|
14358
|
+
value: function ensureCircleLayers() {
|
|
14359
|
+
if (!this.map) return;
|
|
14360
|
+
try {
|
|
14361
|
+
var _this$map$getStyle2;
|
|
14362
|
+
if (!this.map.getSource(CIRCLE_SOURCE_ID)) {
|
|
14363
|
+
this.map.addSource(CIRCLE_SOURCE_ID, {
|
|
14364
|
+
type: "geojson",
|
|
14365
|
+
data: this.circleFeatureCollection()
|
|
14366
|
+
});
|
|
14367
|
+
}
|
|
14368
|
+
var beforeId = (_this$map$getStyle2 = this.map.getStyle()) === null || _this$map$getStyle2 === void 0 || (_this$map$getStyle2 = _this$map$getStyle2.layers) === null || _this$map$getStyle2 === void 0 || (_this$map$getStyle2 = _this$map$getStyle2.find(function (layer) {
|
|
14369
|
+
return layer.type === "symbol";
|
|
14370
|
+
})) === null || _this$map$getStyle2 === void 0 ? void 0 : _this$map$getStyle2.id;
|
|
14371
|
+
if (!this.map.getLayer(CIRCLE_FILL_LAYER_ID)) {
|
|
14372
|
+
var fillLayer = {
|
|
14373
|
+
id: CIRCLE_FILL_LAYER_ID,
|
|
14374
|
+
type: "fill",
|
|
14375
|
+
source: CIRCLE_SOURCE_ID,
|
|
14376
|
+
paint: {
|
|
14377
|
+
"fill-color": ["get", "fillColor"],
|
|
14378
|
+
"fill-opacity": ["get", "fillOpacity"]
|
|
14379
|
+
}
|
|
14380
|
+
};
|
|
14381
|
+
this.map.addLayer(fillLayer, beforeId);
|
|
14382
|
+
}
|
|
14383
|
+
if (!this.map.getLayer(CIRCLE_LINE_LAYER_ID)) {
|
|
14384
|
+
var lineLayer = {
|
|
14385
|
+
id: CIRCLE_LINE_LAYER_ID,
|
|
14386
|
+
type: "line",
|
|
14387
|
+
source: CIRCLE_SOURCE_ID,
|
|
14388
|
+
paint: {
|
|
14389
|
+
"line-color": ["get", "strokeColor"],
|
|
14390
|
+
"line-width": ["get", "strokeWidth"],
|
|
14391
|
+
"line-opacity": ["get", "strokeOpacity"]
|
|
14392
|
+
}
|
|
14393
|
+
};
|
|
14394
|
+
this.map.addLayer(lineLayer, beforeId);
|
|
14395
|
+
}
|
|
14396
|
+
} catch (error) {
|
|
14397
|
+
// Style may not be loaded yet; the styledata listener re-adds the layers
|
|
14398
|
+
}
|
|
14399
|
+
}
|
|
14400
|
+
|
|
14401
|
+
/**
|
|
14402
|
+
* Re-renders all circles: ensures the source and layers exist, then pushes
|
|
14403
|
+
* the current FeatureCollection. Called after every mutation of the circle
|
|
14404
|
+
* list, on floor changes, and when the map style reloads.
|
|
14405
|
+
*/
|
|
14406
|
+
}, {
|
|
14407
|
+
key: "refreshCircles",
|
|
14408
|
+
value: function refreshCircles() {
|
|
14409
|
+
if (!this.map) return;
|
|
14410
|
+
if (this.circles.length === 0 && !this.map.getSource(CIRCLE_SOURCE_ID)) return;
|
|
14411
|
+
this.ensureCircleLayers();
|
|
14412
|
+
try {
|
|
14413
|
+
var source = this.map.getSource(CIRCLE_SOURCE_ID);
|
|
14414
|
+
source === null || source === void 0 || source.setData(this.circleFeatureCollection());
|
|
14415
|
+
} catch (error) {
|
|
14416
|
+
// Source may not exist while a new style is loading
|
|
14417
|
+
}
|
|
14418
|
+
}
|
|
13854
14419
|
|
|
13855
14420
|
/**
|
|
13856
14421
|
* Use it to change the current layer
|
|
@@ -13870,6 +14435,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
13870
14435
|
}
|
|
13871
14436
|
this.updateFiltersTo(floorKeyString);
|
|
13872
14437
|
this.updateMarkersTo(floorKeyString);
|
|
14438
|
+
this.refreshCircles();
|
|
13873
14439
|
this.routeController.updateRouteLayers(floorKeyString);
|
|
13874
14440
|
this.routeController.updateRouteMarkerVisibility(floorKeyString);
|
|
13875
14441
|
}
|
|
@@ -13881,12 +14447,12 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
13881
14447
|
}, {
|
|
13882
14448
|
key: "updateMarkersTo",
|
|
13883
14449
|
value: function updateMarkersTo(floorId) {
|
|
13884
|
-
var _this$innerFloors$
|
|
13885
|
-
_this$innerFloors$
|
|
14450
|
+
var _this$innerFloors$fin8,
|
|
14451
|
+
_this$innerFloors$fin9,
|
|
13886
14452
|
_this1 = this;
|
|
13887
|
-
var isOutdoor = !this.parentPlace || ((_this$innerFloors$
|
|
14453
|
+
var isOutdoor = !this.parentPlace || ((_this$innerFloors$fin8 = (_this$innerFloors$fin9 = this.innerFloors.find(function (floor) {
|
|
13888
14454
|
return floor.key === floorId;
|
|
13889
|
-
})) === null || _this$innerFloors$
|
|
14455
|
+
})) === null || _this$innerFloors$fin9 === void 0 ? void 0 : _this$innerFloors$fin9.reachableFromGPS) !== null && _this$innerFloors$fin8 !== void 0 ? _this$innerFloors$fin8 : false);
|
|
13890
14456
|
this.markers.forEach(function (e) {
|
|
13891
14457
|
e.changeFloor(floorId, _this1.map, isOutdoor);
|
|
13892
14458
|
});
|
|
@@ -13895,19 +14461,19 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
13895
14461
|
key: "updateFiltersTo",
|
|
13896
14462
|
value: function updateFiltersTo(floorId) {
|
|
13897
14463
|
var _this$map$getStyle$la2,
|
|
13898
|
-
_this$map$
|
|
14464
|
+
_this$map$getStyle3,
|
|
13899
14465
|
_this10 = this,
|
|
13900
|
-
_this$innerFloors$
|
|
14466
|
+
_this$innerFloors$fin0;
|
|
13901
14467
|
if (!this.map) return;
|
|
13902
|
-
var layers = (_this$map$getStyle$la2 = (_this$map$
|
|
14468
|
+
var layers = (_this$map$getStyle$la2 = (_this$map$getStyle3 = this.map.getStyle()) === null || _this$map$getStyle3 === void 0 ? void 0 : _this$map$getStyle3.layers) !== null && _this$map$getStyle$la2 !== void 0 ? _this$map$getStyle$la2 : [];
|
|
13903
14469
|
layers.filter(function (l) {
|
|
13904
14470
|
return l.id.startsWith("base-indoor-");
|
|
13905
14471
|
}).forEach(function (l) {
|
|
13906
14472
|
_this10.map.removeLayer(l.id);
|
|
13907
14473
|
});
|
|
13908
|
-
var baseFloorId = (_this$innerFloors$
|
|
14474
|
+
var baseFloorId = (_this$innerFloors$fin0 = this.innerFloors.find(function (floor) {
|
|
13909
14475
|
return floor.key === floorId;
|
|
13910
|
-
})) === null || _this$innerFloors$
|
|
14476
|
+
})) === null || _this$innerFloors$fin0 === void 0 ? void 0 : _this$innerFloors$fin0.baseFloor;
|
|
13911
14477
|
var indoorLayers = layers.filter(function (layer) {
|
|
13912
14478
|
return layer.id.startsWith("indoor-");
|
|
13913
14479
|
});
|
|
@@ -14424,7 +14990,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
14424
14990
|
filter: ["all", ["has", "ref"], ["==", ["get", "ref"], "unselected"]],
|
|
14425
14991
|
paint: {
|
|
14426
14992
|
"fill-extrusion-height": 2.5,
|
|
14427
|
-
"fill-extrusion-color":
|
|
14993
|
+
"fill-extrusion-color": MAPVX_BRAND_COLOR,
|
|
14428
14994
|
"fill-extrusion-opacity": 0.8
|
|
14429
14995
|
}
|
|
14430
14996
|
};
|
|
@@ -14437,7 +15003,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
14437
15003
|
"source-layer": "area",
|
|
14438
15004
|
filter: ["all", ["has", "ref"], ["==", ["get", "ref"], "unselected"]],
|
|
14439
15005
|
paint: {
|
|
14440
|
-
"fill-color":
|
|
15006
|
+
"fill-color": MAPVX_BRAND_COLOR
|
|
14441
15007
|
}
|
|
14442
15008
|
};
|
|
14443
15009
|
this.map.addLayer(_layer);
|
|
@@ -14446,10 +15012,10 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
14446
15012
|
}, {
|
|
14447
15013
|
key: "createBasicFilters",
|
|
14448
15014
|
value: function createBasicFilters() {
|
|
14449
|
-
var _this$parentPlaceId3, _this$
|
|
15015
|
+
var _this$parentPlaceId3, _this$currentFloor4;
|
|
14450
15016
|
var publicPlaceFilter = ["==", ["get", "public_place"], true];
|
|
14451
15017
|
var subPlaceFilter = ["!", ["in", (_this$parentPlaceId3 = this.parentPlaceId) !== null && _this$parentPlaceId3 !== void 0 ? _this$parentPlaceId3 : "noRef", ["get", "is_subplace"]]];
|
|
14452
|
-
var floorId = (_this$
|
|
15018
|
+
var floorId = (_this$currentFloor4 = this.currentFloor) !== null && _this$currentFloor4 !== void 0 ? _this$currentFloor4 : "noRef";
|
|
14453
15019
|
var floorFilter = ["in", floorId, ["get", "floor_key"]];
|
|
14454
15020
|
var showInFloorFilter = ["in", floorId, ["get", "show_in_floor"]];
|
|
14455
15021
|
var basicFilters = publicPlaceFilter;
|
|
@@ -14831,7 +15397,7 @@ var InternalMapVXMap = /*#__PURE__*/function (_Loggeable) {
|
|
|
14831
15397
|
"source-layer": "area",
|
|
14832
15398
|
filter: ["all", ["has", "ref"], ["==", ["get", "ref"], "unselected"]],
|
|
14833
15399
|
paint: {
|
|
14834
|
-
"line-color":
|
|
15400
|
+
"line-color": MAPVX_BRAND_COLOR,
|
|
14835
15401
|
"line-width": 4
|
|
14836
15402
|
}
|
|
14837
15403
|
};
|
|
@@ -17054,6 +17620,136 @@ function is24Hours(openingTime) {
|
|
|
17054
17620
|
// Check if open is "00:00" and close is "24:00" or "00:00"
|
|
17055
17621
|
return open === "00:00" && close === "24:00" || open === "00:00" && close === "00:00";
|
|
17056
17622
|
}
|
|
17623
|
+
;// ./src/utils/preconnect.ts
|
|
17624
|
+
function preconnect_createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = preconnect_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; } } }; }
|
|
17625
|
+
function preconnect_unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return preconnect_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) ? preconnect_arrayLikeToArray(r, a) : void 0; } }
|
|
17626
|
+
function preconnect_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; }
|
|
17627
|
+
/**
|
|
17628
|
+
* Hostnames that MapVX maps typically need to talk to during the first
|
|
17629
|
+
* paint: vector tiles, sprite, glyphs and indoor tile sources. Exposed so
|
|
17630
|
+
* that consumer apps can call `injectPreconnects(MAPVX_DEFAULT_PRECONNECT_HOSTS)`
|
|
17631
|
+
* without having to maintain the list themselves.
|
|
17632
|
+
*
|
|
17633
|
+
* @group Utils
|
|
17634
|
+
*/
|
|
17635
|
+
var MAPVX_DEFAULT_PRECONNECT_HOSTS = ["https://tiles.mapvx.com", "https://api.maptiler.com", "https://indoorequals.mapvx.com"];
|
|
17636
|
+
|
|
17637
|
+
/**
|
|
17638
|
+
* Injects `<link rel="preconnect">` (and a `<link rel="dns-prefetch">` fallback)
|
|
17639
|
+
* tags into `document.head` for the given origins, so the browser starts the
|
|
17640
|
+
* DNS + TLS handshake before MapLibre actually requests sprite/glyph/tile
|
|
17641
|
+
* resources.
|
|
17642
|
+
*
|
|
17643
|
+
* Call this as early as possible — ideally before {@link initializeSDK} — to
|
|
17644
|
+
* maximize the savings. In real captures this shaves ~150-300 ms off the
|
|
17645
|
+
* first-paint cascade.
|
|
17646
|
+
*
|
|
17647
|
+
* Idempotent: hosts that already have a `<link rel="preconnect" crossorigin>`
|
|
17648
|
+
* are skipped. If an existing `preconnect` link is missing `crossorigin`, it
|
|
17649
|
+
* is upgraded in place (added `crossorigin="anonymous"`) — without that
|
|
17650
|
+
* attribute the warmed socket can't be reused for the CORS tile/font/sprite
|
|
17651
|
+
* fetches MapLibre performs, so leaving the existing link untouched would
|
|
17652
|
+
* silently defeat the optimization. Existing `crossorigin="use-credentials"`
|
|
17653
|
+
* is respected and never overwritten.
|
|
17654
|
+
*
|
|
17655
|
+
* @param hosts - Origin URLs (`"https://tiles.mapvx.com"`) or bare hostnames
|
|
17656
|
+
* (`"tiles.mapvx.com"`, normalized to `https://`). Invalid entries are
|
|
17657
|
+
* silently ignored.
|
|
17658
|
+
* @returns The origins where the helper made a change — either a new link was
|
|
17659
|
+
* appended, or an existing one was upgraded with `crossorigin="anonymous"`.
|
|
17660
|
+
*
|
|
17661
|
+
* @example
|
|
17662
|
+
* ```ts
|
|
17663
|
+
* import { initializeSDK, injectPreconnects, MAPVX_DEFAULT_PRECONNECT_HOSTS } from "@mapvx/web-js"
|
|
17664
|
+
*
|
|
17665
|
+
* injectPreconnects(MAPVX_DEFAULT_PRECONNECT_HOSTS)
|
|
17666
|
+
* const sdk = initializeSDK(apiKey)
|
|
17667
|
+
* ```
|
|
17668
|
+
*
|
|
17669
|
+
* @group Utils
|
|
17670
|
+
*/
|
|
17671
|
+
function injectPreconnects(hosts) {
|
|
17672
|
+
if (typeof document === "undefined" || !document.head) return [];
|
|
17673
|
+
if (!Array.isArray(hosts) || hosts.length === 0) return [];
|
|
17674
|
+
var injected = [];
|
|
17675
|
+
var _iterator = preconnect_createForOfIteratorHelper(hosts),
|
|
17676
|
+
_step;
|
|
17677
|
+
try {
|
|
17678
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
17679
|
+
var raw = _step.value;
|
|
17680
|
+
if (typeof raw !== "string" || raw.length === 0) continue;
|
|
17681
|
+
var origin = normalizeOrigin(raw);
|
|
17682
|
+
if (origin === null) continue;
|
|
17683
|
+
|
|
17684
|
+
// Check what's already in <head>. We may need to UPGRADE an existing
|
|
17685
|
+
// preconnect — server-rendered or hand-authored hints frequently omit
|
|
17686
|
+
// `crossorigin`, and a warmed socket without it cannot be reused for
|
|
17687
|
+
// the CORS tile/font/sprite fetches that MapLibre performs. Without
|
|
17688
|
+
// this branch the optimization would silently no-op when the page
|
|
17689
|
+
// already had a partial hint.
|
|
17690
|
+
var existingPreconnect = findLinkForOrigin("preconnect", origin);
|
|
17691
|
+
var preconnectChanged = false;
|
|
17692
|
+
if (existingPreconnect) {
|
|
17693
|
+
if (!existingPreconnect.hasAttribute("crossorigin")) {
|
|
17694
|
+
existingPreconnect.crossOrigin = "anonymous";
|
|
17695
|
+
preconnectChanged = true;
|
|
17696
|
+
}
|
|
17697
|
+
// If the existing link already has any `crossorigin` value
|
|
17698
|
+
// (including `use-credentials`), respect the author's intent and
|
|
17699
|
+
// leave it alone.
|
|
17700
|
+
} else {
|
|
17701
|
+
var preconnect = document.createElement("link");
|
|
17702
|
+
preconnect.rel = "preconnect";
|
|
17703
|
+
preconnect.href = origin;
|
|
17704
|
+
preconnect.crossOrigin = "anonymous";
|
|
17705
|
+
document.head.appendChild(preconnect);
|
|
17706
|
+
preconnectChanged = true;
|
|
17707
|
+
}
|
|
17708
|
+
|
|
17709
|
+
// dns-prefetch is a fallback for older browsers that ignore preconnect.
|
|
17710
|
+
if (!findLinkForOrigin("dns-prefetch", origin)) {
|
|
17711
|
+
var dnsPrefetch = document.createElement("link");
|
|
17712
|
+
dnsPrefetch.rel = "dns-prefetch";
|
|
17713
|
+
dnsPrefetch.href = origin;
|
|
17714
|
+
document.head.appendChild(dnsPrefetch);
|
|
17715
|
+
}
|
|
17716
|
+
if (preconnectChanged) injected.push(origin);
|
|
17717
|
+
}
|
|
17718
|
+
} catch (err) {
|
|
17719
|
+
_iterator.e(err);
|
|
17720
|
+
} finally {
|
|
17721
|
+
_iterator.f();
|
|
17722
|
+
}
|
|
17723
|
+
return injected;
|
|
17724
|
+
}
|
|
17725
|
+
|
|
17726
|
+
/**
|
|
17727
|
+
* Returns the first `<link rel="${rel}">` in `<head>` whose resolved origin
|
|
17728
|
+
* matches `origin`, or null. We compare canonical URL origins instead of
|
|
17729
|
+
* the raw `href` attribute text — the same origin can be written as
|
|
17730
|
+
* `https://tiles.mapvx.com` or `https://tiles.mapvx.com/`, and a strict
|
|
17731
|
+
* attribute selector would miss the second form and inject a duplicate.
|
|
17732
|
+
*/
|
|
17733
|
+
function findLinkForOrigin(rel, origin) {
|
|
17734
|
+
var links = document.head.querySelectorAll("link[rel=\"".concat(rel, "\"]"));
|
|
17735
|
+
for (var i = 0; i < links.length; i++) {
|
|
17736
|
+
var link = links[i];
|
|
17737
|
+
try {
|
|
17738
|
+
if (new URL(link.href).origin === origin) return link;
|
|
17739
|
+
} catch (_unused) {
|
|
17740
|
+
// Malformed href — skip and keep scanning.
|
|
17741
|
+
}
|
|
17742
|
+
}
|
|
17743
|
+
return null;
|
|
17744
|
+
}
|
|
17745
|
+
function normalizeOrigin(raw) {
|
|
17746
|
+
try {
|
|
17747
|
+
var candidate = /^https?:\/\//i.test(raw) ? raw : "https://".concat(raw);
|
|
17748
|
+
return new URL(candidate).origin;
|
|
17749
|
+
} catch (_unused2) {
|
|
17750
|
+
return null;
|
|
17751
|
+
}
|
|
17752
|
+
}
|
|
17057
17753
|
;// ./src/index.ts
|
|
17058
17754
|
// ─── Domain Ports (interfaces) ───────────────────────────────────────────────
|
|
17059
17755
|
|
|
@@ -17085,6 +17781,8 @@ function is24Hours(openingTime) {
|
|
|
17085
17781
|
|
|
17086
17782
|
// ─── Domain Models: Categories ───────────────────────────────────────────────
|
|
17087
17783
|
|
|
17784
|
+
// ─── Domain Models: Circle ───────────────────────────────────────────────────
|
|
17785
|
+
|
|
17088
17786
|
|
|
17089
17787
|
// ─── Domain Models: City Filter ──────────────────────────────────────────────
|
|
17090
17788
|
|
|
@@ -17135,6 +17833,7 @@ function is24Hours(openingTime) {
|
|
|
17135
17833
|
|
|
17136
17834
|
|
|
17137
17835
|
|
|
17836
|
+
|
|
17138
17837
|
/**
|
|
17139
17838
|
* Function to load default styles
|
|
17140
17839
|
* @group Utils
|