@mapcreator/sdk 0.0.7 → 0.0.9
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/{HighlightManager.d.ts → esm/HighlightManager.d.ts} +2 -2
- package/dist/esm/HighlightManager.js +203 -0
- package/dist/{MCMap.d.ts → esm/MCMap.d.ts} +3 -5
- package/dist/esm/MCMap.js +254 -0
- package/dist/{PopupManager.d.ts → esm/PopupManager.d.ts} +4 -4
- package/dist/esm/PopupManager.js +297 -0
- package/dist/{Registry.d.ts → esm/Registry.d.ts} +3 -3
- package/dist/esm/Registry.js +74 -0
- package/dist/{adornments → esm/adornments}/categoricalLegend.d.ts +1 -1
- package/dist/esm/adornments/categoricalLegend.js +141 -0
- package/dist/{adornments → esm/adornments}/connectedLegend.d.ts +2 -2
- package/dist/esm/adornments/connectedLegend.js +393 -0
- package/dist/{adornments → esm/adornments}/customAdornment.d.ts +1 -1
- package/dist/esm/adornments/customAdornment.js +29 -0
- package/dist/{adornments → esm/adornments}/heading.d.ts +1 -1
- package/dist/esm/adornments/heading.js +71 -0
- package/dist/esm/adornments/insetMap.d.ts +3 -0
- package/dist/esm/adornments/insetMap.js +351 -0
- package/dist/{adornments → esm/adornments}/manualLegend.d.ts +1 -1
- package/dist/esm/adornments/manualLegend.js +15 -0
- package/dist/esm/adornments/northArrow.d.ts +3 -0
- package/dist/esm/adornments/northArrow.js +24 -0
- package/dist/esm/adornments/scalebar.d.ts +3 -0
- package/dist/esm/adornments/scalebar.js +176 -0
- package/dist/{constants → esm/constants}/index.d.ts +2 -2
- package/dist/esm/constants/index.js +53 -0
- package/dist/esm/controls/controls.js +7 -0
- package/dist/{controls → esm/controls}/fullscreenControls.d.ts +1 -1
- package/dist/esm/controls/fullscreenControls.js +29 -0
- package/dist/{controls → esm/controls}/geocoderControl.d.ts +1 -1
- package/dist/esm/controls/geocoderControl.js +202 -0
- package/dist/{controls → esm/controls}/geolocationControls.d.ts +1 -1
- package/dist/esm/controls/geolocationControls.js +65 -0
- package/dist/esm/controls/refreshMapControls.d.ts +3 -0
- package/dist/esm/controls/refreshMapControls.js +26 -0
- package/dist/esm/controls/webControls.d.ts +4 -0
- package/dist/esm/controls/webControls.js +40 -0
- package/dist/{controls → esm/controls}/zoomControls.d.ts +1 -1
- package/dist/esm/controls/zoomControls.js +23 -0
- package/dist/esm/i18n.js +21 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/locales/da_DK/strings.json +7 -0
- package/dist/esm/locales/de_DE/strings.json +7 -0
- package/dist/esm/locales/en_GB/strings.json +7 -0
- package/dist/esm/locales/es_ES/strings.json +7 -0
- package/dist/esm/locales/fr_FR/strings.json +7 -0
- package/dist/esm/locales/it_IT/strings.json +7 -0
- package/dist/esm/locales/nl_NL/strings.json +7 -0
- package/dist/esm/models/area.d.ts +5 -0
- package/dist/esm/models/area.js +165 -0
- package/dist/esm/models/circle.d.ts +5 -0
- package/dist/esm/models/circle.js +110 -0
- package/dist/esm/models/dot.d.ts +3 -0
- package/dist/esm/models/dot.js +42 -0
- package/dist/esm/models/line.d.ts +4 -0
- package/dist/esm/models/line.js +117 -0
- package/dist/esm/models/marker.d.ts +5 -0
- package/dist/esm/models/marker.js +179 -0
- package/dist/esm/models/polygon.d.ts +5 -0
- package/dist/esm/models/polygon.js +80 -0
- package/dist/{renderAdornments.d.ts → esm/renderAdornments.d.ts} +3 -3
- package/dist/esm/renderAdornments.js +129 -0
- package/dist/esm/types/geometry.js +1 -0
- package/dist/{types → esm/types}/index.d.ts +1 -1
- package/dist/esm/types/index.js +1 -0
- package/dist/esm/types/jobObject.js +1 -0
- package/dist/{types → esm/types}/mapstyle.d.ts +6 -2
- package/dist/esm/types/mapstyle.js +1 -0
- package/dist/esm/utils/browser.js +6 -0
- package/dist/{utils → esm/utils}/choropleth.d.ts +3 -3
- package/dist/esm/utils/choropleth.js +110 -0
- package/dist/esm/utils/fullscreen.js +40 -0
- package/dist/{utils → esm/utils}/geolocation.d.ts +1 -1
- package/dist/esm/utils/geolocation.js +93 -0
- package/dist/{utils → esm/utils}/graphhopper.d.ts +1 -1
- package/dist/esm/utils/graphhopper.js +41 -0
- package/dist/{utils → esm/utils}/helpers.d.ts +2 -2
- package/dist/esm/utils/helpers.js +116 -0
- package/dist/{utils → esm/utils}/language.d.ts +1 -1
- package/dist/esm/utils/language.js +170 -0
- package/dist/{utils → esm/utils}/models.d.ts +4 -4
- package/dist/esm/utils/models.js +103 -0
- package/dist/{utils → esm/utils}/overlays.d.ts +1 -1
- package/dist/esm/utils/overlays.js +87 -0
- package/dist/esm/utils/scalebar.js +52 -0
- package/dist/{utils → esm/utils}/svgHelpers.d.ts +4 -3
- package/dist/esm/utils/svgHelpers.js +1512 -0
- package/dist/{utils → esm/utils}/template.d.ts +2 -2
- package/dist/esm/utils/template.js +120 -0
- package/dist/{utils → esm/utils}/youtube.d.ts +1 -1
- package/dist/esm/utils/youtube.js +64 -0
- package/dist/favicon-32x32.png +0 -0
- package/dist/mapcreator-sdk.umd.cjs +91 -91
- package/dist/report.html +4950 -0
- package/package.json +7 -7
- package/dist/adornments/insetMap.d.ts +0 -3
- package/dist/adornments/northArrow.d.ts +0 -3
- package/dist/adornments/scalebar.d.ts +0 -3
- package/dist/controls/refreshMapControls.d.ts +0 -3
- package/dist/controls/webControls.d.ts +0 -4
- package/dist/index.d.ts +0 -2
- package/dist/locales/da_DK/strings.json.d.ts +0 -10
- package/dist/locales/de_DE/strings.json.d.ts +0 -10
- package/dist/locales/en_GB/strings.json.d.ts +0 -10
- package/dist/locales/es_ES/strings.json.d.ts +0 -10
- package/dist/locales/fr_FR/strings.json.d.ts +0 -10
- package/dist/locales/it_IT/strings.json.d.ts +0 -10
- package/dist/locales/nl_NL/strings.json.d.ts +0 -10
- package/dist/mapcreator-sdk.js +0 -39590
- package/dist/models/area.d.ts +0 -5
- package/dist/models/circle.d.ts +0 -5
- package/dist/models/dot.d.ts +0 -3
- package/dist/models/line.d.ts +0 -4
- package/dist/models/marker.d.ts +0 -5
- package/dist/models/polygon.d.ts +0 -5
- /package/dist/{controls → esm/controls}/controls.d.ts +0 -0
- /package/dist/{i18n.d.ts → esm/i18n.d.ts} +0 -0
- /package/dist/{types → esm/types}/geometry.d.ts +0 -0
- /package/dist/{types → esm/types}/jobObject.d.ts +0 -0
- /package/dist/{utils → esm/utils}/browser.d.ts +0 -0
- /package/dist/{utils → esm/utils}/fullscreen.d.ts +0 -0
- /package/dist/{utils → esm/utils}/scalebar.d.ts +0 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
export function setLanguage(language, map) {
|
|
2
|
+
for (const layer of map.getStyle().layers) {
|
|
3
|
+
if (layer.type !== 'symbol' || layer.id.startsWith('custom-') || layer.id.startsWith('gl-')) {
|
|
4
|
+
continue;
|
|
5
|
+
}
|
|
6
|
+
const textField = layer.layout && layer.layout['text-field'];
|
|
7
|
+
if (layer['source-layer'] &&
|
|
8
|
+
Array.isArray(textField) &&
|
|
9
|
+
textField[0] === 'coalesce' &&
|
|
10
|
+
!textField.find(item => Array.isArray(item) && item[1] === 'name:abbr')) {
|
|
11
|
+
map.setLayoutProperty(layer.id, 'text-field', textFieldExpression(layer.source, language), {
|
|
12
|
+
validate: false,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function textFieldExpression(source, language) {
|
|
18
|
+
if (language !== 'en' && language !== 'native') {
|
|
19
|
+
language = transformLanguageCode(language, LanguageNotation.TWO);
|
|
20
|
+
}
|
|
21
|
+
if (language === 'native') {
|
|
22
|
+
return ['get', 'name'];
|
|
23
|
+
}
|
|
24
|
+
if (source.startsWith('mc-base')) {
|
|
25
|
+
return [
|
|
26
|
+
'coalesce',
|
|
27
|
+
['get', `name:${language}`],
|
|
28
|
+
['case', ['has', 'name_is_latin'], ['get', 'name'], ['get', 'name:en']],
|
|
29
|
+
];
|
|
30
|
+
}
|
|
31
|
+
return ['coalesce', ['get', `name:${language}`], ['get', 'name:en'], ['get', 'name']];
|
|
32
|
+
}
|
|
33
|
+
export const LanguageNotation = Object.freeze({
|
|
34
|
+
THREE: 'ISO 639-2/B',
|
|
35
|
+
API: 'ISO 639-2/B',
|
|
36
|
+
TWO: 'ISO 639-1',
|
|
37
|
+
MAPLIBRE_COMPAT: 'ISO 639-1',
|
|
38
|
+
ENDONYM: 'name', // Endonym is the native name of a language
|
|
39
|
+
NAME: 'name', // We should add the ISO language names using this field
|
|
40
|
+
LOCALE: 'locale',
|
|
41
|
+
i18n: 'locale',
|
|
42
|
+
});
|
|
43
|
+
// The first language *must* be english because we use this as a fallback
|
|
44
|
+
export const LanguageCodes = Object.freeze([
|
|
45
|
+
{
|
|
46
|
+
[LanguageNotation.TWO]: 'en',
|
|
47
|
+
[LanguageNotation.THREE]: 'eng',
|
|
48
|
+
[LanguageNotation.ENDONYM]: 'English',
|
|
49
|
+
[LanguageNotation.LOCALE]: 'en_GB',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
[LanguageNotation.TWO]: 'da',
|
|
53
|
+
[LanguageNotation.THREE]: 'dan',
|
|
54
|
+
[LanguageNotation.ENDONYM]: 'Dansk',
|
|
55
|
+
[LanguageNotation.LOCALE]: 'da_DK',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
[LanguageNotation.TWO]: 'nl',
|
|
59
|
+
[LanguageNotation.THREE]: 'dut',
|
|
60
|
+
[LanguageNotation.ENDONYM]: 'Nederlands',
|
|
61
|
+
[LanguageNotation.LOCALE]: 'nl_NL',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
[LanguageNotation.TWO]: 'fi',
|
|
65
|
+
[LanguageNotation.THREE]: 'fin',
|
|
66
|
+
[LanguageNotation.ENDONYM]: 'Suomi',
|
|
67
|
+
[LanguageNotation.LOCALE]: 'fi_FI',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
[LanguageNotation.TWO]: 'fr',
|
|
71
|
+
[LanguageNotation.THREE]: 'fre',
|
|
72
|
+
[LanguageNotation.ENDONYM]: 'Francais',
|
|
73
|
+
[LanguageNotation.LOCALE]: 'fr_FR',
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
[LanguageNotation.TWO]: 'de',
|
|
77
|
+
[LanguageNotation.THREE]: 'ger',
|
|
78
|
+
[LanguageNotation.ENDONYM]: 'Deutsch',
|
|
79
|
+
[LanguageNotation.LOCALE]: 'de_DE',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
[LanguageNotation.TWO]: 'it',
|
|
83
|
+
[LanguageNotation.THREE]: 'ita',
|
|
84
|
+
[LanguageNotation.ENDONYM]: 'Italiano',
|
|
85
|
+
[LanguageNotation.LOCALE]: 'it_IT',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
[LanguageNotation.TWO]: 'no',
|
|
89
|
+
[LanguageNotation.THREE]: 'nor',
|
|
90
|
+
[LanguageNotation.ENDONYM]: 'Norsk',
|
|
91
|
+
[LanguageNotation.LOCALE]: 'nn_NO',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
[LanguageNotation.TWO]: 'pl',
|
|
95
|
+
[LanguageNotation.THREE]: 'pol',
|
|
96
|
+
[LanguageNotation.ENDONYM]: 'Polski',
|
|
97
|
+
[LanguageNotation.LOCALE]: 'pl_PL',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
[LanguageNotation.TWO]: 'pt',
|
|
101
|
+
[LanguageNotation.THREE]: 'por',
|
|
102
|
+
[LanguageNotation.ENDONYM]: 'Portugues',
|
|
103
|
+
[LanguageNotation.LOCALE]: 'pt_PT',
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
[LanguageNotation.TWO]: 'es',
|
|
107
|
+
[LanguageNotation.THREE]: 'spa',
|
|
108
|
+
[LanguageNotation.ENDONYM]: 'Espanol',
|
|
109
|
+
[LanguageNotation.LOCALE]: 'es_ES',
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
[LanguageNotation.TWO]: 'sv',
|
|
113
|
+
[LanguageNotation.THREE]: 'swe',
|
|
114
|
+
[LanguageNotation.ENDONYM]: 'Svenska',
|
|
115
|
+
[LanguageNotation.LOCALE]: 'sv_SE',
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
[LanguageNotation.TWO]: 'ja',
|
|
119
|
+
[LanguageNotation.THREE]: 'jpn',
|
|
120
|
+
[LanguageNotation.ENDONYM]: '日本語',
|
|
121
|
+
[LanguageNotation.LOCALE]: 'ja_JP',
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
[LanguageNotation.TWO]: 'zh',
|
|
125
|
+
[LanguageNotation.THREE]: 'chi',
|
|
126
|
+
[LanguageNotation.ENDONYM]: '汉语',
|
|
127
|
+
[LanguageNotation.LOCALE]: 'zh_CN',
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
[LanguageNotation.TWO]: 'ru',
|
|
131
|
+
[LanguageNotation.THREE]: 'rus',
|
|
132
|
+
[LanguageNotation.ENDONYM]: 'Русский',
|
|
133
|
+
[LanguageNotation.LOCALE]: 'ru_RU',
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
[LanguageNotation.TWO]: 'uk',
|
|
137
|
+
[LanguageNotation.THREE]: 'ukr',
|
|
138
|
+
[LanguageNotation.ENDONYM]: 'Украї́нська',
|
|
139
|
+
[LanguageNotation.LOCALE]: 'uk_UK',
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
[LanguageNotation.TWO]: 'lv',
|
|
143
|
+
[LanguageNotation.THREE]: 'lav',
|
|
144
|
+
[LanguageNotation.ENDONYM]: 'Latviešu valoda',
|
|
145
|
+
[LanguageNotation.LOCALE]: 'lv-LV',
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
[LanguageNotation.TWO]: 'kk',
|
|
149
|
+
[LanguageNotation.THREE]: 'kaz',
|
|
150
|
+
[LanguageNotation.ENDONYM]: 'қазақша',
|
|
151
|
+
[LanguageNotation.LOCALE]: 'kk-KZ',
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
[LanguageNotation.TWO]: 'ar',
|
|
155
|
+
[LanguageNotation.THREE]: 'ara',
|
|
156
|
+
[LanguageNotation.ENDONYM]: 'العربية',
|
|
157
|
+
[LanguageNotation.LOCALE]: 'ar_SA',
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
[LanguageNotation.TWO]: 'native',
|
|
161
|
+
[LanguageNotation.THREE]: 'native',
|
|
162
|
+
[LanguageNotation.ENDONYM]: 'Native',
|
|
163
|
+
[LanguageNotation.LOCALE]: 'native',
|
|
164
|
+
},
|
|
165
|
+
]);
|
|
166
|
+
export function transformLanguageCode(input, type = LanguageNotation.MAPLIBRE_COMPAT) {
|
|
167
|
+
const language = LanguageCodes.find(lang => Object.values(lang).some(value => value === input)) ??
|
|
168
|
+
LanguageCodes[0];
|
|
169
|
+
return language[type];
|
|
170
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { LngLat, Position } from '
|
|
2
|
-
import { JobObjectPolygon } from '
|
|
3
|
-
import { ModelBindings } from '
|
|
4
|
-
import { Map } from '@mapcreator/maplibre-gl';
|
|
1
|
+
import type { LngLat, Position } from '@/types/geometry';
|
|
2
|
+
import type { JobObjectPolygon } from '@/types/jobObject';
|
|
3
|
+
import type { ModelBindings } from '@/types';
|
|
4
|
+
import type { Map } from '@mapcreator/maplibre-gl';
|
|
5
5
|
export declare function calculateCircle(center: LngLat, radius: number): Array<[number, number]>;
|
|
6
6
|
export declare function calculateRadiusLine(center: LngLat, radius: number, bearing: number): Position[];
|
|
7
7
|
export declare function calculatePolygonGeometry(polygon: JobObjectPolygon): Position[][];
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { degToRad, radToDeg, calcDistance, numberRe, fnv32b } from '@/utils/helpers';
|
|
2
|
+
import { lineString, polygon as makePolygon } from '@turf/helpers';
|
|
3
|
+
import { polygonSmooth } from '@turf/polygon-smooth';
|
|
4
|
+
import bboxClip from '@turf/bbox-clip';
|
|
5
|
+
export function calculateCircle(center, radius) {
|
|
6
|
+
const circle = [];
|
|
7
|
+
const steps = 100;
|
|
8
|
+
const interval = (Math.PI * 2) / steps;
|
|
9
|
+
for (let i = 0; i < steps; i++) {
|
|
10
|
+
circle.push(calculateCirclePoint(center, radius, i * interval));
|
|
11
|
+
}
|
|
12
|
+
if (containsNorthPole(center, radius)) {
|
|
13
|
+
const first = circle[0];
|
|
14
|
+
const last = circle[circle.length - 1];
|
|
15
|
+
const lng = (last[0] + first[0] - 360) / 2;
|
|
16
|
+
const lat = (first[1] + last[1]) / 2;
|
|
17
|
+
circle.push([lng, lat]);
|
|
18
|
+
circle.push([lng, 90]);
|
|
19
|
+
circle.push([lng + 360, 90]);
|
|
20
|
+
circle.push([lng + 360, lat]);
|
|
21
|
+
}
|
|
22
|
+
if (containsSouthPole(center, radius)) {
|
|
23
|
+
const first = circle[49];
|
|
24
|
+
const last = circle[50];
|
|
25
|
+
const lng = (last[0] + first[0] - 360) / 2;
|
|
26
|
+
const lat = (first[1] + last[1]) / 2;
|
|
27
|
+
circle.splice(50, 0, [lng + 360, lat], [lng + 360, -90], [lng, -90], [lng, lat]);
|
|
28
|
+
}
|
|
29
|
+
circle.push(circle[0]);
|
|
30
|
+
return circle;
|
|
31
|
+
}
|
|
32
|
+
export function calculateRadiusLine(center, radius, bearing) {
|
|
33
|
+
const points = [];
|
|
34
|
+
const steps = 100;
|
|
35
|
+
const interval = radius / steps;
|
|
36
|
+
for (let i = 0; i <= steps; i++) {
|
|
37
|
+
points.push(calculateCirclePoint(center, i * interval, degToRad(bearing)));
|
|
38
|
+
}
|
|
39
|
+
const bbox = [-Infinity, -85.051129, Infinity, 85.051129];
|
|
40
|
+
return bboxClip(lineString(points), bbox).geometry.coordinates;
|
|
41
|
+
}
|
|
42
|
+
function calculateCirclePoint(center, radius, bearing) {
|
|
43
|
+
const earthRadius = 6378.1;
|
|
44
|
+
const radiusRatio = radius / earthRadius;
|
|
45
|
+
const lngCenter = degToRad(center.lng);
|
|
46
|
+
const latCenter = degToRad(center.lat);
|
|
47
|
+
const lat = Math.asin(Math.sin(latCenter) * Math.cos(radiusRatio) +
|
|
48
|
+
Math.cos(latCenter) * Math.sin(radiusRatio) * Math.cos(bearing));
|
|
49
|
+
const lng = lngCenter +
|
|
50
|
+
Math.atan2(Math.sin(bearing) * Math.sin(radiusRatio) * Math.cos(latCenter), Math.cos(radiusRatio) - Math.sin(latCenter) * Math.sin(lat));
|
|
51
|
+
return [radToDeg(lng), radToDeg(lat)];
|
|
52
|
+
}
|
|
53
|
+
function containsNorthPole(center, radius) {
|
|
54
|
+
return calcDistance(center, { lng: 0, lat: 90 }) / 1000 < radius;
|
|
55
|
+
}
|
|
56
|
+
function containsSouthPole(center, radius) {
|
|
57
|
+
return calcDistance(center, { lng: 0, lat: -90 }) / 1000 < radius;
|
|
58
|
+
}
|
|
59
|
+
export function calculatePolygonGeometry(polygon) {
|
|
60
|
+
const { polygonType } = polygon;
|
|
61
|
+
const anchorPoints = typeof polygon.anchorPoints?.[0]?.[0] === 'number'
|
|
62
|
+
? [polygon.anchorPoints]
|
|
63
|
+
: polygon.anchorPoints;
|
|
64
|
+
if (polygonType === 'smooth') {
|
|
65
|
+
return (polygonSmooth(makePolygon(anchorPoints), { iterations: 4 }).features?.[0]?.geometry
|
|
66
|
+
?.coordinates ?? anchorPoints.slice());
|
|
67
|
+
}
|
|
68
|
+
return anchorPoints.slice();
|
|
69
|
+
}
|
|
70
|
+
export function getAreaLayerId(groupId, area) {
|
|
71
|
+
const key = fnv32b(`${area.vectorUrl}/${area.sourceLayerId}`);
|
|
72
|
+
return `${groupId}-${key}`;
|
|
73
|
+
}
|
|
74
|
+
export function getAreaSourceId(area) {
|
|
75
|
+
return `custom-area-${fnv32b(area.vectorUrl)}`;
|
|
76
|
+
}
|
|
77
|
+
export function getBoundValues(modelBindings, dataColumn) {
|
|
78
|
+
return modelBindings.reduce((result, bindings) => {
|
|
79
|
+
const value = bindings.dataBindings?.[dataColumn];
|
|
80
|
+
if (typeof value === 'object' && value !== null && value.t === 'n') {
|
|
81
|
+
result.push(value.v);
|
|
82
|
+
}
|
|
83
|
+
else if (typeof value === 'number') {
|
|
84
|
+
result.push(value);
|
|
85
|
+
}
|
|
86
|
+
else if (typeof value === 'string' && value) {
|
|
87
|
+
result.push(numberRe.test(value) ? Number(value) : value);
|
|
88
|
+
}
|
|
89
|
+
return result;
|
|
90
|
+
}, []);
|
|
91
|
+
}
|
|
92
|
+
export function getLineAngle(line, map) {
|
|
93
|
+
const n = line.length;
|
|
94
|
+
if (n < 2) {
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
const endPoint = map.projectWithScaleCorrection(line[n - 1]);
|
|
98
|
+
const penultimatePoint = map.projectWithScaleCorrection(line[n - 2]);
|
|
99
|
+
const dx = endPoint.x - penultimatePoint.x;
|
|
100
|
+
const dy = penultimatePoint.y - endPoint.y;
|
|
101
|
+
const thetaDeg = Math.atan2(dy, dx) * (180 / Math.PI);
|
|
102
|
+
return (90 - thetaDeg + 360) % 360;
|
|
103
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Map, LayerSpecification } from '@mapcreator/maplibre-gl';
|
|
1
|
+
import type { Map, LayerSpecification } from '@mapcreator/maplibre-gl';
|
|
2
2
|
export declare function loadOverlays(overlays: string[], map: Map, vapiUrl: string, accessToken: string, styleOverrides?: {
|
|
3
3
|
[layerId: string]: Partial<LayerSpecification>;
|
|
4
4
|
}): Promise<void>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
export async function loadOverlays(overlays, map, vapiUrl, accessToken, styleOverrides) {
|
|
2
|
+
const urls = overlays.map(overlay => `${vapiUrl}/styles/${overlay}.json?access_token=${accessToken}`);
|
|
3
|
+
const promises = urls.map(url => fetch(url).then(result => result.json()));
|
|
4
|
+
const data = await Promise.all(promises);
|
|
5
|
+
await Promise.all(data.map(item => addOverlay(item, map, accessToken, styleOverrides)));
|
|
6
|
+
}
|
|
7
|
+
async function addOverlay(data, map, accessToken, styleOverrides) {
|
|
8
|
+
for (const sourceId in data.sources) {
|
|
9
|
+
if (map.getSource(sourceId) === undefined) {
|
|
10
|
+
map.addSource(sourceId, data.sources[sourceId]);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
if (data.sprite !== undefined) {
|
|
14
|
+
await loadSprite(map, data.sprite, accessToken);
|
|
15
|
+
}
|
|
16
|
+
for (const layer of data.layers) {
|
|
17
|
+
if (map.getLayer(layer.id) !== undefined) {
|
|
18
|
+
map.removeLayer(layer.id);
|
|
19
|
+
}
|
|
20
|
+
const addBefore = layer.metadata?.['mc-add-before'] ?? 'mc-before-none';
|
|
21
|
+
map.addLayer(applyOverrides(layer, styleOverrides), addBefore);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function applyOverrides(layer, styleOverrides) {
|
|
25
|
+
const overrides = styleOverrides ?? {};
|
|
26
|
+
const override = overrides[layer.id] ?? {};
|
|
27
|
+
const result = {
|
|
28
|
+
...layer,
|
|
29
|
+
layout: { ...layer.layout, ...override.layout },
|
|
30
|
+
paint: { ...layer.paint, ...override.paint },
|
|
31
|
+
metadata: {
|
|
32
|
+
...layer.metadata,
|
|
33
|
+
...override.metadata,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
if (override.minzoom !== undefined) {
|
|
37
|
+
result.minzoom = override.minzoom;
|
|
38
|
+
}
|
|
39
|
+
if (override.maxzoom !== undefined) {
|
|
40
|
+
result.maxzoom = override.maxzoom;
|
|
41
|
+
}
|
|
42
|
+
if ('filter' in override && result.type !== 'background') {
|
|
43
|
+
result.filter = override.filter;
|
|
44
|
+
}
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
async function loadSprite(map, spriteUrl, accessToken) {
|
|
48
|
+
try {
|
|
49
|
+
const spriteJsonUrl = `${spriteUrl}.json?access_token=${accessToken}`;
|
|
50
|
+
const spriteImageUrl = `${spriteUrl}.png?access_token=${accessToken}`;
|
|
51
|
+
const [spriteJsonResponse, spriteImageResponse] = await Promise.all([
|
|
52
|
+
fetch(spriteJsonUrl),
|
|
53
|
+
fetch(spriteImageUrl),
|
|
54
|
+
]);
|
|
55
|
+
if (!spriteJsonResponse.ok || !spriteImageResponse.ok) {
|
|
56
|
+
throw new Error(`Failed to load sprite from ${spriteUrl}`);
|
|
57
|
+
}
|
|
58
|
+
const spriteJson = await spriteJsonResponse.json();
|
|
59
|
+
const spriteImageBlob = await spriteImageResponse.blob();
|
|
60
|
+
const spriteImage = await new Promise((resolve, reject) => {
|
|
61
|
+
const img = new Image();
|
|
62
|
+
img.onload = () => resolve(img);
|
|
63
|
+
img.onerror = err => reject(err);
|
|
64
|
+
img.src = URL.createObjectURL(spriteImageBlob);
|
|
65
|
+
});
|
|
66
|
+
const canvas = document.createElement('canvas');
|
|
67
|
+
const context = canvas.getContext('2d', { willReadFrequently: true });
|
|
68
|
+
if (!context) {
|
|
69
|
+
throw new Error('Failed to get canvas context');
|
|
70
|
+
}
|
|
71
|
+
for (const [name, sprite] of Object.entries(spriteJson)) {
|
|
72
|
+
if (map.hasImage(name)) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const { x, y, width, height, pixelRatio } = sprite;
|
|
76
|
+
canvas.width = width * pixelRatio;
|
|
77
|
+
canvas.height = height * pixelRatio;
|
|
78
|
+
context.clearRect(0, 0, canvas.width, canvas.height);
|
|
79
|
+
context.drawImage(spriteImage, x, y, width, height, 0, 0, canvas.width, canvas.height);
|
|
80
|
+
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
|
|
81
|
+
map.addImage(name, imageData, { pixelRatio });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
console.error(error);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const significantNumbers = [10, 5, 3, 2, 1];
|
|
2
|
+
export function floatToFraction(x, error = 0.000001) {
|
|
3
|
+
const n = Math.floor(x);
|
|
4
|
+
x -= n;
|
|
5
|
+
if (x < error) {
|
|
6
|
+
return [n, 1];
|
|
7
|
+
}
|
|
8
|
+
else if (1 - error < x) {
|
|
9
|
+
return [n + 1, 1];
|
|
10
|
+
}
|
|
11
|
+
// The lower fraction is 0/1
|
|
12
|
+
let lowerN = 0;
|
|
13
|
+
let lowerD = 1;
|
|
14
|
+
// The upper fraction is 1/1
|
|
15
|
+
let upperN = 1;
|
|
16
|
+
let upperD = 1;
|
|
17
|
+
// eslint-disable-next-line no-constant-condition
|
|
18
|
+
while (true) {
|
|
19
|
+
// The middle fraction is (lowerN upperN) / (lower_d + upperD)
|
|
20
|
+
const middleN = lowerN + upperN;
|
|
21
|
+
const middleD = lowerD + upperD;
|
|
22
|
+
// If x + error < middle
|
|
23
|
+
if (middleD * (x + error) < middleN) {
|
|
24
|
+
// Middle is the new upper
|
|
25
|
+
upperN = middleN;
|
|
26
|
+
upperD = middleD;
|
|
27
|
+
}
|
|
28
|
+
else if (middleN < (x - error) * middleD) {
|
|
29
|
+
// Middle is the new lower
|
|
30
|
+
lowerN = middleN;
|
|
31
|
+
lowerD = middleD;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
// Middle is best fraction
|
|
35
|
+
return [n * middleD + middleN, middleD];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export function getRoundNum(num) {
|
|
40
|
+
const pow10 = 10 ** Math.floor(Math.log10(num));
|
|
41
|
+
const d = num / pow10;
|
|
42
|
+
for (const n of significantNumbers) {
|
|
43
|
+
if (d >= n) {
|
|
44
|
+
return n * pow10;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return getDecimalRoundNum(d) * pow10;
|
|
48
|
+
}
|
|
49
|
+
function getDecimalRoundNum(d) {
|
|
50
|
+
const multiplier = 10 ** Math.ceil(-Math.log(d) / Math.LN10);
|
|
51
|
+
return Math.round(d * multiplier) / multiplier;
|
|
52
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import 'path-data-polyfill';
|
|
2
|
+
import type { JobObjectDataBindings } from '@/types/jobObject';
|
|
3
|
+
import type { Map as MapLibre } from '@mapcreator/maplibre-gl';
|
|
4
|
+
import type { ColorGenerator } from '@/utils/choropleth';
|
|
4
5
|
export declare function escapeXML(str: string): string;
|
|
5
6
|
export declare function loadFonts(fontNames: string[], vapiUrl: string, accessToken: string): Promise<void>;
|
|
6
7
|
export interface SvgColor {
|