@basemaps/landing 6.27.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.
Files changed (73) hide show
  1. package/CHANGELOG.md +1097 -0
  2. package/LICENSE +21 -0
  3. package/README.md +3 -0
  4. package/build/__test__/config.debug.test.d.ts +2 -0
  5. package/build/__test__/config.debug.test.d.ts.map +1 -0
  6. package/build/__test__/config.debug.test.js +28 -0
  7. package/build/__test__/config.test.d.ts +2 -0
  8. package/build/__test__/config.test.d.ts.map +1 -0
  9. package/build/__test__/config.test.js +8 -0
  10. package/build/__test__/geojson.test.d.ts +2 -0
  11. package/build/__test__/geojson.test.d.ts.map +1 -0
  12. package/build/__test__/geojson.test.js +42 -0
  13. package/build/__test__/map.config.test.d.ts +2 -0
  14. package/build/__test__/map.config.test.d.ts.map +1 -0
  15. package/build/__test__/map.config.test.js +103 -0
  16. package/build/__test__/tile.matrix.test.d.ts +2 -0
  17. package/build/__test__/tile.matrix.test.d.ts.map +1 -0
  18. package/build/__test__/tile.matrix.test.js +29 -0
  19. package/build/attribution.d.ts +48 -0
  20. package/build/attribution.d.ts.map +1 -0
  21. package/build/attribution.js +137 -0
  22. package/build/components/copyable.d.ts +14 -0
  23. package/build/components/copyable.d.ts.map +1 -0
  24. package/build/components/copyable.js +26 -0
  25. package/build/components/debug.d.ts +34 -0
  26. package/build/components/debug.d.ts.map +1 -0
  27. package/build/components/debug.js +309 -0
  28. package/build/components/layer.switcher.dropdown.d.ts +21 -0
  29. package/build/components/layer.switcher.dropdown.d.ts.map +1 -0
  30. package/build/components/layer.switcher.dropdown.js +68 -0
  31. package/build/components/layout.footer.d.ts +8 -0
  32. package/build/components/layout.footer.d.ts.map +1 -0
  33. package/build/components/layout.footer.js +23 -0
  34. package/build/components/layout.header.d.ts +23 -0
  35. package/build/components/layout.header.d.ts.map +1 -0
  36. package/build/components/layout.header.js +98 -0
  37. package/build/components/link.d.ts +17 -0
  38. package/build/components/link.d.ts.map +1 -0
  39. package/build/components/link.js +12 -0
  40. package/build/components/map.d.ts +31 -0
  41. package/build/components/map.d.ts.map +1 -0
  42. package/build/components/map.js +136 -0
  43. package/build/components/map.switcher.d.ts +21 -0
  44. package/build/components/map.switcher.d.ts.map +1 -0
  45. package/build/components/map.switcher.js +78 -0
  46. package/build/config.d.ts +15 -0
  47. package/build/config.d.ts.map +1 -0
  48. package/build/config.debug.d.ts +22 -0
  49. package/build/config.debug.d.ts.map +1 -0
  50. package/build/config.debug.js +62 -0
  51. package/build/config.js +43 -0
  52. package/build/config.map.d.ts +51 -0
  53. package/build/config.map.d.ts.map +1 -0
  54. package/build/config.map.js +179 -0
  55. package/build/global.d.ts +9 -0
  56. package/build/global.d.ts.map +1 -0
  57. package/build/global.js +1 -0
  58. package/build/index.d.ts +2 -0
  59. package/build/index.d.ts.map +1 -0
  60. package/build/index.js +21 -0
  61. package/build/split.d.ts +11 -0
  62. package/build/split.d.ts.map +1 -0
  63. package/build/split.js +45 -0
  64. package/build/tile.matrix.d.ts +23 -0
  65. package/build/tile.matrix.d.ts.map +1 -0
  66. package/build/tile.matrix.js +77 -0
  67. package/build/url.d.ts +37 -0
  68. package/build/url.d.ts.map +1 -0
  69. package/build/url.js +78 -0
  70. package/build/webp.d.ts +3 -0
  71. package/build/webp.d.ts.map +1 -0
  72. package/build/webp.js +32 -0
  73. package/package.json +107 -0
@@ -0,0 +1,136 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
2
+ import { GoogleTms } from '@basemaps/geo';
3
+ import maplibre from 'maplibre-gl';
4
+ import { Component } from 'preact';
5
+ import { MapAttribution } from '../attribution.js';
6
+ import { Config } from '../config.js';
7
+ import { SplitIo } from '../split.js';
8
+ import { getTileGrid, locationTransform } from '../tile.matrix.js';
9
+ import { WindowUrl } from '../url.js';
10
+ import { Debug } from './debug.js';
11
+ import { MapSwitcher } from './map.switcher.js';
12
+ export class Basemaps extends Component {
13
+ constructor() {
14
+ super(...arguments);
15
+ /** Ignore the location updates */
16
+ this.ignoreNextLocationUpdate = false;
17
+ this.updateLocation = () => {
18
+ if (this.ignoreNextLocationUpdate) {
19
+ this.ignoreNextLocationUpdate = false;
20
+ return;
21
+ }
22
+ const location = Config.map.location;
23
+ this.map.setZoom(location.zoom);
24
+ this.map.setCenter([location.lon, location.lat]);
25
+ };
26
+ this.updateBounds = (bounds) => {
27
+ if (Config.map.tileMatrix !== GoogleTms) {
28
+ // Transform bounds to current tileMatrix
29
+ const lngLatBounds = maplibre.LngLatBounds.convert(bounds);
30
+ const upperLeft = lngLatBounds.getNorthEast();
31
+ const lowerRight = lngLatBounds.getSouthWest();
32
+ const zoom = this.map.getZoom();
33
+ const upperLeftLocation = locationTransform({ lat: upperLeft.lat, lon: upperLeft.lng, zoom }, Config.map.tileMatrix, GoogleTms);
34
+ const lowerRightLocation = locationTransform({ lat: lowerRight.lat, lon: lowerRight.lng, zoom }, Config.map.tileMatrix, GoogleTms);
35
+ bounds = [
36
+ [upperLeftLocation.lon, upperLeftLocation.lat],
37
+ [lowerRightLocation.lon, lowerRightLocation.lat],
38
+ ];
39
+ }
40
+ this.map.fitBounds(bounds);
41
+ };
42
+ this.updateStyle = () => {
43
+ this.ensureGeoControl();
44
+ const tileGrid = getTileGrid(Config.map.tileMatrix.identifier);
45
+ const style = tileGrid.getStyle(Config.map.layerId, Config.map.style);
46
+ this.map.setStyle(style);
47
+ if (Config.map.tileMatrix !== GoogleTms)
48
+ this.map.setMaxBounds([-180, -85.06, 180, 85.06]);
49
+ else
50
+ this.map.setMaxBounds();
51
+ this.setState(this.state);
52
+ };
53
+ this._events = [];
54
+ this.updateUrlTimer = null;
55
+ this.onRender = () => {
56
+ if (this.updateUrlTimer != null)
57
+ return;
58
+ this.updateUrlTimer = setTimeout(() => this.setLocationUrl(), 1000);
59
+ };
60
+ }
61
+ /**
62
+ * Only show the geocontrol on GoogleTMS
63
+ * As it does not work with the projection logic we are currently using
64
+ */
65
+ ensureGeoControl() {
66
+ if (Config.map.debug['debug.screenshot'])
67
+ return;
68
+ if (Config.map.tileMatrix === GoogleTms) {
69
+ if (this.controlGeo != null)
70
+ return;
71
+ this.controlGeo = new maplibre.GeolocateControl({});
72
+ this.map.addControl(this.controlGeo, 'top-left');
73
+ }
74
+ else {
75
+ if (this.controlGeo == null)
76
+ return;
77
+ this.map.removeControl(this.controlGeo);
78
+ }
79
+ }
80
+ componentWillMount() {
81
+ this.setState({ isLayerSwitcherEnabled: false });
82
+ }
83
+ componentDidMount() {
84
+ // Force the URL to be read before loading the map
85
+ Config.map.updateFromUrl();
86
+ this.el = document.getElementById('map');
87
+ if (this.el == null)
88
+ throw new Error('Unable to find #map element');
89
+ const cfg = Config.map;
90
+ const tileGrid = getTileGrid(cfg.tileMatrix.identifier);
91
+ const style = tileGrid.getStyle(cfg.layerId, cfg.style);
92
+ const location = locationTransform(cfg.location, cfg.tileMatrix, GoogleTms);
93
+ this.map = new maplibre.Map({
94
+ container: this.el,
95
+ style,
96
+ center: [location.lon, location.lat],
97
+ zoom: location.zoom,
98
+ attributionControl: false,
99
+ });
100
+ this.mapAttr = new MapAttribution(this.map);
101
+ if (Config.map.debug['debug.screenshot'] !== true) {
102
+ const nav = new maplibre.NavigationControl({ visualizePitch: true });
103
+ this.map.addControl(nav, 'top-left');
104
+ this.map.addControl(new maplibre.FullscreenControl({ container: this.el }));
105
+ }
106
+ this.map.on('render', this.onRender);
107
+ this.map.on('load', () => {
108
+ this._events.push(Config.map.on('location', this.updateLocation), Config.map.on('tileMatrix', this.updateStyle), Config.map.on('layer', this.updateStyle), Config.map.on('bounds', this.updateBounds));
109
+ this.updateStyle();
110
+ });
111
+ SplitIo.getClient().then((f) => {
112
+ const isEnabled = (f === null || f === void 0 ? void 0 : f.getTreatment('layer-switcher-button')) === 'on';
113
+ this.setState({ isLayerSwitcherEnabled: isEnabled });
114
+ });
115
+ }
116
+ componentWillUnmount() {
117
+ if (this.map)
118
+ this.map.remove();
119
+ for (const unbind of this._events)
120
+ unbind();
121
+ this._events = [];
122
+ }
123
+ render() {
124
+ const isLayerSwitcherEnabled = this.state.isLayerSwitcherEnabled && Config.map.tileMatrix === GoogleTms && !Config.map.isDebug;
125
+ return (_jsxs("div", { style: { flex: 1, position: 'relative' }, children: [_jsx("div", { id: "map", style: { width: '100%', height: '100%' } }), Config.map.isDebug ? _jsx(Debug, { map: this.map }) : undefined, isLayerSwitcherEnabled ? _jsx(MapSwitcher, {}) : undefined] }));
126
+ }
127
+ /** Update the window.location with the current location information */
128
+ setLocationUrl() {
129
+ this.updateUrlTimer = null;
130
+ const location = Config.map.getLocation(this.map);
131
+ this.ignoreNextLocationUpdate = true;
132
+ Config.map.setLocation(location);
133
+ const path = WindowUrl.toHash(location);
134
+ window.history.replaceState(null, '', path);
135
+ }
136
+ }
@@ -0,0 +1,21 @@
1
+ /// <reference types="node" />
2
+ import maplibre from 'maplibre-gl';
3
+ import { Component, ComponentChild } from 'preact';
4
+ export declare class MapSwitcher extends Component {
5
+ _events: (() => boolean)[];
6
+ map: maplibre.Map;
7
+ el: HTMLDivElement;
8
+ currentStyle: string;
9
+ componentDidMount(): void;
10
+ componentWillUnmount(): void;
11
+ getStyleType(): {
12
+ layerId: string;
13
+ style?: string;
14
+ };
15
+ _updateTimer: NodeJS.Timer | null;
16
+ update: () => void;
17
+ updateMap: () => void;
18
+ switchLayer: () => void;
19
+ render(): ComponentChild;
20
+ }
21
+ //# sourceMappingURL=map.switcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map.switcher.d.ts","sourceRoot":"","sources":["../../src/components/map.switcher.tsx"],"names":[],"mappings":";AAAA,OAAO,QAAQ,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAKnD,qBAAa,WAAY,SAAQ,SAAS;IACxC,OAAO,EAAE,CAAC,MAAM,OAAO,CAAC,EAAE,CAAM;IAChC,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC;IAClB,EAAE,EAAE,cAAc,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IAErB,iBAAiB,IAAI,IAAI;IAkCzB,oBAAoB,IAAI,IAAI;IAK5B,YAAY,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAKnD,YAAY,EAAE,MAAM,CAAC,KAAK,GAAG,IAAI,CAAQ;IACzC,MAAM,QAAO,IAAI,CAGf;IAEF,SAAS,QAAO,IAAI,CAelB;IAEF,WAAW,QAAO,IAAI,CAKpB;IAEF,MAAM,IAAI,cAAc;CAQzB"}
@@ -0,0 +1,78 @@
1
+ import { jsx as _jsx } from "preact/jsx-runtime";
2
+ import maplibre from 'maplibre-gl';
3
+ import { Component } from 'preact';
4
+ import { Config } from '../config.js';
5
+ import { MapConfig } from '../config.map.js';
6
+ import { getTileGrid } from '../tile.matrix.js';
7
+ export class MapSwitcher extends Component {
8
+ constructor() {
9
+ super(...arguments);
10
+ this._events = [];
11
+ this._updateTimer = null;
12
+ this.update = () => {
13
+ if (this._updateTimer != null)
14
+ return;
15
+ this._updateTimer = setTimeout(this.updateMap, 1000);
16
+ };
17
+ this.updateMap = () => {
18
+ this._updateTimer = null;
19
+ const location = Config.map.transformedLocation;
20
+ const target = this.getStyleType();
21
+ const styleId = `${target.layerId}::${target.style}`;
22
+ if (this.currentStyle !== styleId) {
23
+ const tileGrid = getTileGrid(Config.map.tileMatrix.identifier);
24
+ const style = tileGrid.getStyle(target.layerId, target.style);
25
+ this.currentStyle = styleId;
26
+ this.map.setStyle(style);
27
+ }
28
+ this.map.setZoom(Math.max(location.zoom - 4, 0));
29
+ this.map.setCenter([location.lon, location.lat]);
30
+ this.setState(this.state);
31
+ };
32
+ this.switchLayer = () => {
33
+ const target = this.getStyleType();
34
+ Config.map.setLayerId(target.layerId, target.style);
35
+ this.updateMap();
36
+ window.history.pushState(null, '', `?${MapConfig.toUrl(Config.map)}`);
37
+ };
38
+ }
39
+ componentDidMount() {
40
+ // Force the URL to be read before loading the map
41
+ Config.map.updateFromUrl();
42
+ this.el = document.getElementById('map-switcher-map');
43
+ if (this.el == null)
44
+ return;
45
+ const cfg = Config.map;
46
+ const tileGrid = getTileGrid(cfg.tileMatrix.identifier);
47
+ const target = this.getStyleType();
48
+ this.currentStyle = `${target.layerId}::${target.style}`;
49
+ const style = tileGrid.getStyle(target.layerId, target.style);
50
+ const location = cfg.transformedLocation;
51
+ this.map = new maplibre.Map({
52
+ container: this.el,
53
+ style,
54
+ center: [location.lon, location.lat],
55
+ zoom: location.zoom,
56
+ attributionControl: false,
57
+ });
58
+ this.map.on('load', () => {
59
+ this._events.push(Config.map.on('location', this.update), Config.map.on('tileMatrix', this.update), Config.map.on('layer', this.update), Config.map.on('bounds', this.update));
60
+ this.updateMap();
61
+ });
62
+ }
63
+ componentWillUnmount() {
64
+ if (this.map)
65
+ this.map.remove();
66
+ for (const e of this._events)
67
+ e();
68
+ }
69
+ getStyleType() {
70
+ if (Config.map.layerId !== 'aerial')
71
+ return { layerId: 'aerial' };
72
+ return { layerId: 'topographic', style: 'topographic' };
73
+ }
74
+ render() {
75
+ const layerTitle = `Switch map to ${this.getStyleType().layerId}`;
76
+ return (_jsx("div", { id: "map-switcher", class: "map-switcher", onClick: this.switchLayer, title: layerTitle, children: _jsx("div", { id: "map-switcher-map", style: { width: '100%', height: '100%', pointerEvents: 'none' } }) }));
77
+ }
78
+ }
@@ -0,0 +1,15 @@
1
+ import { MapConfig } from './config.map.js';
2
+ export declare const Config: {
3
+ readonly BaseUrl: string;
4
+ readonly ApiKey: string;
5
+ readonly GoogleAnalytics: string;
6
+ readonly Version: string;
7
+ readonly SplitApiKey: string;
8
+ map: MapConfig;
9
+ };
10
+ export declare const enum GaEvent {
11
+ TileTiming = "TileTiming",
12
+ Ui = "Ui"
13
+ }
14
+ export declare function gaEvent(category: GaEvent, action: string, value?: number): void;
15
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,eAAO,MAAM,MAAM;;;;;;;CAiBlB,CAAC;AAgBF,0BAAkB,OAAO;IACvB,UAAU,eAAe;IACzB,EAAE,OAAO;CACV;AAED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAG/E"}
@@ -0,0 +1,22 @@
1
+ export interface DebugState {
2
+ debug: boolean;
3
+ /** What color should the background be */
4
+ 'debug.background': string | false;
5
+ /** Should the source tiles */
6
+ 'debug.source': boolean;
7
+ /** Should things be hidden to make a better screenshot */
8
+ 'debug.screenshot': boolean;
9
+ /** What opacity is the aerial layer, 0 is off */
10
+ 'debug.layer.linz-aerial': number;
11
+ /** What opacity is the topographic layer, 0 is off */
12
+ 'debug.layer.linz-topographic': number;
13
+ /** What opacity is the open streetmap layer, 0 is off*/
14
+ 'debug.layer.osm': number;
15
+ }
16
+ export declare const DebugDefaults: DebugState;
17
+ export declare class ConfigDebug {
18
+ static toUrl(opt: DebugState, url: URLSearchParams): void;
19
+ static fromUrl(opt: DebugState, url: URLSearchParams): boolean;
20
+ }
21
+ export declare type DebugKeysNumber = keyof DebugState;
22
+ //# sourceMappingURL=config.debug.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.debug.d.ts","sourceRoot":"","sources":["../src/config.debug.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,0CAA0C;IAC1C,kBAAkB,EAAE,MAAM,GAAG,KAAK,CAAC;IACnC,8BAA8B;IAC9B,cAAc,EAAE,OAAO,CAAC;IACxB,0DAA0D;IAC1D,kBAAkB,EAAE,OAAO,CAAC;IAC5B,iDAAiD;IACjD,yBAAyB,EAAE,MAAM,CAAC;IAClC,sDAAsD;IACtD,8BAA8B,EAAE,MAAM,CAAC;IACvC,wDAAwD;IACxD,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,aAAa,EAAE,UAQ3B,CAAC;AAEF,qBAAa,WAAW;IACtB,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,eAAe,GAAG,IAAI;IAYzD,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO;CAoB/D;AAgBD,oBAAY,eAAe,GAAG,MAAM,UAAU,CAAC"}
@@ -0,0 +1,62 @@
1
+ export const DebugDefaults = {
2
+ debug: false,
3
+ 'debug.background': false,
4
+ 'debug.source': false,
5
+ 'debug.screenshot': false,
6
+ 'debug.layer.linz-aerial': 0,
7
+ 'debug.layer.linz-topographic': 0,
8
+ 'debug.layer.osm': 0,
9
+ };
10
+ export class ConfigDebug {
11
+ static toUrl(opt, url) {
12
+ if (opt.debug !== true)
13
+ return;
14
+ url.append('debug', 'true');
15
+ for (const [key, value] of Object.entries(opt)) {
16
+ if (key === 'debug')
17
+ continue;
18
+ const defaultVal = DebugDefaults[key];
19
+ if (defaultVal === value)
20
+ continue;
21
+ url.append(key, String(value));
22
+ }
23
+ }
24
+ static fromUrl(opt, url) {
25
+ const isDebug = url.get('debug') != null;
26
+ let isChanged = false;
27
+ if (isDebug === false) {
28
+ // Debug is off reset to default
29
+ for (const [key, value] of Object.entries(DebugDefaults)) {
30
+ isChanged = setKey(opt, key, value) || isChanged;
31
+ }
32
+ return isChanged;
33
+ }
34
+ isChanged = setKey(opt, 'debug', true);
35
+ isChanged = setKey(opt, 'debug.background', url.get('debug.background')) || isChanged;
36
+ isChanged = setKey(opt, 'debug.source', url.get('debug.source') != null) || isChanged;
37
+ isChanged = setKey(opt, 'debug.screenshot', url.get('debug.screenshot') != null) || isChanged;
38
+ isChanged = setNum(opt, 'debug.layer.linz-aerial', url.get('debug.layer.linz-aerial')) || isChanged;
39
+ isChanged = setNum(opt, 'debug.layer.linz-topographic', url.get('debug.layer.linz-topographic')) || isChanged;
40
+ isChanged = setNum(opt, 'debug.layer.osm', url.get('debug.layer.osm')) || isChanged;
41
+ return isChanged;
42
+ }
43
+ }
44
+ function toNum(val, defaultValue = 0) {
45
+ if (val == null)
46
+ return defaultValue;
47
+ const num = Number(val);
48
+ if (isNaN(num))
49
+ return defaultValue;
50
+ return num;
51
+ }
52
+ function setKey(opt, key, value) {
53
+ if (value == null)
54
+ value = DebugDefaults[key];
55
+ if (opt[key] === value)
56
+ return false;
57
+ opt[key] = value;
58
+ return true;
59
+ }
60
+ function setNum(opt, key, value) {
61
+ return setKey(opt, key, toNum(value));
62
+ }
@@ -0,0 +1,43 @@
1
+ import { getApiKey } from '@basemaps/shared/build/api.js';
2
+ import { MapConfig } from './config.map.js';
3
+ const currentApiKey = getApiKey();
4
+ export const Config = {
5
+ get BaseUrl() {
6
+ var _a;
7
+ return (_a = process.env.TILE_HOST) !== null && _a !== void 0 ? _a : '';
8
+ },
9
+ get ApiKey() {
10
+ return currentApiKey;
11
+ },
12
+ get GoogleAnalytics() {
13
+ var _a;
14
+ return (_a = process.env.GOOGLE_ANALYTICS) !== null && _a !== void 0 ? _a : '';
15
+ },
16
+ get Version() {
17
+ var _a;
18
+ return (_a = process.env.GIT_VERSION) !== null && _a !== void 0 ? _a : '';
19
+ },
20
+ get SplitApiKey() {
21
+ var _a;
22
+ return (_a = process.env.SPLIT_IO_KEY) !== null && _a !== void 0 ? _a : '';
23
+ },
24
+ map: new MapConfig(),
25
+ };
26
+ // Inject google analytics after everything has loaded
27
+ if (Config.GoogleAnalytics !== '' && typeof window !== 'undefined') {
28
+ window.dataLayer = window.dataLayer || [];
29
+ window.gtag = function gtag() {
30
+ window.dataLayer.push(arguments); // eslint-disable-line prefer-rest-params
31
+ };
32
+ window.gtag('js', new Date());
33
+ window.gtag('config', `${Config.GoogleAnalytics}`);
34
+ const script = document.createElement('script');
35
+ script.setAttribute('async', '');
36
+ script.setAttribute('src', `https://www.googletagmanager.com/gtag/js?id=${Config.GoogleAnalytics}`);
37
+ document.head.appendChild(script);
38
+ }
39
+ export function gaEvent(category, action, value) {
40
+ if (Config.GoogleAnalytics === '')
41
+ return;
42
+ window.gtag('event', action, { event_category: category, value });
43
+ }
@@ -0,0 +1,51 @@
1
+ import { EpsgCode, TileMatrixSet } from '@basemaps/geo';
2
+ import { Emitter } from '@servie/events';
3
+ import maplibregl, { LngLatBoundsLike } from 'maplibre-gl';
4
+ import { DebugState } from './config.debug.js';
5
+ import { MapLocation, MapOptionType } from './url.js';
6
+ export interface MapConfigEvents {
7
+ location: [MapLocation];
8
+ tileMatrix: [TileMatrixSet];
9
+ layer: [string, string | null | undefined];
10
+ bounds: [LngLatBoundsLike];
11
+ change: null;
12
+ }
13
+ export declare class MapConfig extends Emitter<MapConfigEvents> {
14
+ style: string | null;
15
+ layerId: string;
16
+ tileMatrix: TileMatrixSet;
17
+ debug: DebugState;
18
+ private _layers;
19
+ get layers(): Promise<Map<string, LayerInfo>>;
20
+ get isDebug(): boolean;
21
+ /** Map location in WGS84 */
22
+ _location: MapLocation;
23
+ get location(): MapLocation;
24
+ /** Map location in tileMatrix projection */
25
+ get transformedLocation(): MapLocation;
26
+ get isVector(): boolean;
27
+ /** Key to reference the combined layer & style */
28
+ get layerKey(): string;
29
+ /** Key to reference combined layer & style & tile matrix */
30
+ get layerKeyTms(): string;
31
+ updateFromUrl(search?: string): void;
32
+ static toUrl(opts: MapConfig): string;
33
+ toTileUrl(urlType: MapOptionType, tileMatrix?: TileMatrixSet, layerId?: string, style?: string | null): string;
34
+ getLocation(map: maplibregl.Map): MapLocation;
35
+ transformLocation(lat: number, lon: number, zoom: number): MapLocation;
36
+ setLocation(l: MapLocation): void;
37
+ setTileMatrix(tms: TileMatrixSet): void;
38
+ setLayerId(layer: string, style?: string | null): void;
39
+ setDebug<T extends keyof DebugState>(key: T, value?: DebugState[T]): void;
40
+ }
41
+ export interface LayerInfo {
42
+ /** Layer id to use when fetching tiles */
43
+ id: string;
44
+ /** Layer name */
45
+ name: string;
46
+ upperLeft: [number, number];
47
+ lowerRight: [number, number];
48
+ /** What projections are enabled for this layer */
49
+ projections: Set<EpsgCode>;
50
+ }
51
+ //# sourceMappingURL=config.map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.map.d.ts","sourceRoot":"","sources":["../src/config.map.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,QAAQ,EAA2C,aAAa,EAAkB,MAAM,eAAe,CAAC;AACvH,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,UAAU,EAAE,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,UAAU,EAA8B,MAAM,mBAAmB,CAAC;AAG3E,OAAO,EAAE,WAAW,EAAE,aAAa,EAAa,MAAM,UAAU,CAAC;AASjE,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,CAAC,WAAW,CAAC,CAAC;IACxB,UAAU,EAAE,CAAC,aAAa,CAAC,CAAC;IAC5B,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IAC3C,MAAM,EAAE,CAAC,gBAAgB,CAAC,CAAC;IAC3B,MAAM,EAAE,IAAI,CAAC;CACd;AAED,qBAAa,SAAU,SAAQ,OAAO,CAAC,eAAe,CAAC;IACrD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC5B,OAAO,SAAY;IACnB,UAAU,EAAE,aAAa,CAAa;IAEtC,KAAK,EAAE,UAAU,CAAwB;IAEzC,OAAO,CAAC,OAAO,CAAkC;IACjD,IAAI,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAG5C;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,4BAA4B;IAC5B,SAAS,EAAE,WAAW,CAAC;IACvB,IAAI,QAAQ,IAAI,WAAW,CAc1B;IAED,4CAA4C;IAC5C,IAAI,mBAAmB,IAAI,WAAW,CAErC;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,mDAAmD;IACnD,IAAI,QAAQ,IAAI,MAAM,CAGrB;IAED,4DAA4D;IAC5D,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,aAAa,CAAC,MAAM,GAAE,MAA+B,GAAG,IAAI;IA2B5D,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM;IASrC,SAAS,CAAC,OAAO,EAAE,aAAa,EAAE,UAAU,gBAAkB,EAAE,OAAO,SAAe,EAAE,KAAK,gBAAa,GAAG,MAAM;IAInH,WAAW,CAAC,GAAG,EAAE,UAAU,CAAC,GAAG,GAAG,WAAW;IAO7C,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW;IAItE,WAAW,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI;IASjC,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI;IAMvC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAQtD,QAAQ,CAAC,CAAC,SAAS,MAAM,UAAU,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,GAAE,UAAU,CAAC,CAAC,CAAsB,GAAG,IAAI;CAK9F;AAED,MAAM,WAAW,SAAS;IACxB,0CAA0C;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IAEb,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,kDAAkD;IAClD,WAAW,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;CAC5B"}
@@ -0,0 +1,179 @@
1
+ import { Epsg, GoogleTms, Nztm2000QuadTms, Nztm2000Tms, TileMatrixSets } from '@basemaps/geo';
2
+ import { Emitter } from '@servie/events';
3
+ import { DebugDefaults, ConfigDebug } from './config.debug.js';
4
+ import { Config } from './config.js';
5
+ import { locationTransform } from './tile.matrix.js';
6
+ import { WindowUrl } from './url.js';
7
+ /** Default center point if none provided */
8
+ const DefaultCenter = {
9
+ [GoogleTms.identifier]: { lat: -41.88999621, lon: 174.04924373, zoom: 5 },
10
+ [Nztm2000Tms.identifier]: { lat: -41.277848, lon: 174.6763921, zoom: 3 },
11
+ [Nztm2000QuadTms.identifier]: { lat: -41.88999621, lon: 174.04924373, zoom: 3 },
12
+ };
13
+ export class MapConfig extends Emitter {
14
+ constructor() {
15
+ super(...arguments);
16
+ this.style = null;
17
+ this.layerId = 'aerial';
18
+ this.tileMatrix = GoogleTms;
19
+ this.debug = { ...DebugDefaults };
20
+ }
21
+ get layers() {
22
+ if (this._layers == null)
23
+ this._layers = loadAllLayers();
24
+ return this._layers;
25
+ }
26
+ get isDebug() {
27
+ return this.debug.debug;
28
+ }
29
+ get location() {
30
+ if (this._location == null) {
31
+ window.addEventListener('popstate', () => {
32
+ const location = {
33
+ ...DefaultCenter[this.tileMatrix.identifier],
34
+ ...WindowUrl.fromHash(window.location.hash),
35
+ };
36
+ this.setLocation(location);
37
+ });
38
+ this.updateFromUrl();
39
+ this._location = { ...DefaultCenter[this.tileMatrix.identifier], ...WindowUrl.fromHash(window.location.hash) };
40
+ }
41
+ return this._location;
42
+ }
43
+ /** Map location in tileMatrix projection */
44
+ get transformedLocation() {
45
+ return this.transformLocation(this.location.lat, this.location.lon, this.location.zoom);
46
+ }
47
+ get isVector() {
48
+ return this.layerId === 'topographic';
49
+ }
50
+ /** Key to reference the combined layer & style */
51
+ get layerKey() {
52
+ if (this.style == null)
53
+ return this.layerId;
54
+ return `${this.layerId}::${this.style}`;
55
+ }
56
+ /** Key to reference combined layer & style & tile matrix */
57
+ get layerKeyTms() {
58
+ return `${this.layerKey}::${this.tileMatrix.identifier}`;
59
+ }
60
+ updateFromUrl(search = window.location.search) {
61
+ var _a, _b, _c, _d;
62
+ const urlParams = new URLSearchParams(search);
63
+ const style = (_a = urlParams.get('s')) !== null && _a !== void 0 ? _a : urlParams.get('style');
64
+ const layerId = (_b = urlParams.get('i')) !== null && _b !== void 0 ? _b : 'aerial';
65
+ const projectionParam = ((_c = urlParams.get('p')) !== null && _c !== void 0 ? _c : GoogleTms.identifier).toLowerCase();
66
+ let tileMatrix = TileMatrixSets.All.find((f) => f.identifier.toLowerCase() === projectionParam);
67
+ if (tileMatrix == null)
68
+ tileMatrix = TileMatrixSets.get((_d = Epsg.parse(projectionParam)) !== null && _d !== void 0 ? _d : Epsg.Google);
69
+ if (tileMatrix.identifier === Nztm2000Tms.identifier)
70
+ tileMatrix = Nztm2000QuadTms;
71
+ const debugChanged = ConfigDebug.fromUrl(this.debug, urlParams);
72
+ if (debugChanged)
73
+ this.emit('change');
74
+ const previousUrl = MapConfig.toUrl(this);
75
+ this.style = style !== null && style !== void 0 ? style : null;
76
+ this.layerId = layerId.startsWith('im_') ? layerId.slice(3) : layerId;
77
+ this.tileMatrix = tileMatrix;
78
+ if (this.layerId === 'topographic' && this.style == null)
79
+ this.style = 'topographic';
80
+ this.emit('tileMatrix', this.tileMatrix);
81
+ this.emit('layer', this.layerId, this.style);
82
+ if (previousUrl !== MapConfig.toUrl(this))
83
+ this.emit('change');
84
+ }
85
+ static toUrl(opts) {
86
+ const urlParams = new URLSearchParams();
87
+ if (opts.style)
88
+ urlParams.append('s', opts.style);
89
+ if (opts.layerId !== 'aerial')
90
+ urlParams.append('i', opts.layerId);
91
+ if (opts.tileMatrix.identifier !== GoogleTms.identifier)
92
+ urlParams.append('p', opts.tileMatrix.identifier);
93
+ ConfigDebug.toUrl(opts.debug, urlParams);
94
+ return urlParams.toString();
95
+ }
96
+ toTileUrl(urlType, tileMatrix = this.tileMatrix, layerId = this.layerId, style = this.style) {
97
+ return WindowUrl.toTileUrl(urlType, tileMatrix, layerId, style);
98
+ }
99
+ getLocation(map) {
100
+ var _a;
101
+ const center = map.getCenter();
102
+ if (center == null)
103
+ throw new Error('Invalid Map location');
104
+ const zoom = Math.floor(((_a = map.getZoom()) !== null && _a !== void 0 ? _a : 0) * 10e3) / 10e3;
105
+ return Config.map.transformLocation(center.lat, center.lng, zoom);
106
+ }
107
+ transformLocation(lat, lon, zoom) {
108
+ return locationTransform({ lat, lon, zoom }, GoogleTms, this.tileMatrix);
109
+ }
110
+ setLocation(l) {
111
+ if (l.lat === this.location.lat && l.lon === this.location.lon && l.zoom === this.location.zoom)
112
+ return;
113
+ this.location.lat = l.lat;
114
+ this.location.lon = l.lon;
115
+ this.location.zoom = l.zoom;
116
+ this.emit('location', this.location);
117
+ this.emit('change');
118
+ }
119
+ setTileMatrix(tms) {
120
+ if (this.tileMatrix.identifier === tms.identifier)
121
+ return;
122
+ this.emit('tileMatrix', this.tileMatrix);
123
+ this.emit('change');
124
+ }
125
+ setLayerId(layer, style) {
126
+ if (this.layerId === layer && this.style === style)
127
+ return;
128
+ this.layerId = layer;
129
+ this.style = style !== null && style !== void 0 ? style : null;
130
+ this.emit('layer', this.layerId, this.style);
131
+ this.emit('change');
132
+ }
133
+ setDebug(key, value = DebugDefaults[key]) {
134
+ if (this.debug[key] === value)
135
+ return;
136
+ this.debug[key] = value;
137
+ this.emit('change');
138
+ }
139
+ }
140
+ async function loadAllLayers() {
141
+ var _a, _b, _c, _d, _e, _f, _g, _h;
142
+ const output = new Map();
143
+ const res = await fetch(WindowUrl.toBaseWmts());
144
+ if (!res.ok)
145
+ return output;
146
+ const dom = new DOMParser();
147
+ const xmlDoc = dom.parseFromString(await res.text(), 'text/xml');
148
+ const layers = xmlDoc.getElementsByTagName('Layer');
149
+ const allLayers = [];
150
+ for (let i = 0; i < layers.length; i++) {
151
+ const layer = layers.item(i);
152
+ if (layer == null)
153
+ continue;
154
+ const title = (_a = layer.getElementsByTagName('ows:Title').item(0)) === null || _a === void 0 ? void 0 : _a.textContent;
155
+ const id = (_b = layer.getElementsByTagName('ows:Identifier').item(0)) === null || _b === void 0 ? void 0 : _b.textContent;
156
+ if (title == null || id == null)
157
+ continue;
158
+ if (title === 'aerial')
159
+ continue;
160
+ const boundEl = layer.getElementsByTagName('ows:WGS84BoundingBox').item(0);
161
+ const upperLeft = (_d = (_c = boundEl === null || boundEl === void 0 ? void 0 : boundEl.getElementsByTagName('ows:UpperCorner').item(0)) === null || _c === void 0 ? void 0 : _c.textContent) === null || _d === void 0 ? void 0 : _d.split(' ').map(Number);
162
+ const lowerRight = (_f = (_e = boundEl === null || boundEl === void 0 ? void 0 : boundEl.getElementsByTagName('ows:LowerCorner').item(0)) === null || _e === void 0 ? void 0 : _e.textContent) === null || _f === void 0 ? void 0 : _f.split(' ').map(Number);
163
+ const tmsTags = layer.getElementsByTagName('TileMatrixSet');
164
+ const projections = new Set();
165
+ for (let j = 0; j < tmsTags.length; j++) {
166
+ const epsg = Epsg.parse((_h = (_g = tmsTags.item(j)) === null || _g === void 0 ? void 0 : _g.textContent) !== null && _h !== void 0 ? _h : '');
167
+ if (epsg == null)
168
+ continue;
169
+ projections.add(epsg.code);
170
+ }
171
+ if (upperLeft == null || lowerRight == null || upperLeft.length !== 2)
172
+ continue;
173
+ allLayers.push({ id, name: title.replace('aerial ', ''), upperLeft, lowerRight, projections });
174
+ }
175
+ allLayers.sort((a, b) => a.name.localeCompare(b.name));
176
+ for (const l of allLayers)
177
+ output.set(l.id, l);
178
+ return output;
179
+ }
@@ -0,0 +1,9 @@
1
+ import { SplitIo } from './split.js';
2
+ declare global {
3
+ interface Window {
4
+ dataLayer: any[];
5
+ gtag(...args: any[]): void;
6
+ splitIo: typeof SplitIo;
7
+ }
8
+ }
9
+ //# sourceMappingURL=global.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global.d.ts","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QAEd,SAAS,EAAE,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QAE3B,OAAO,EAAE,OAAO,OAAO,CAAC;KACzB;CACF"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":""}