@mapcreator/sdk 0.0.9 → 0.0.10
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/{esm/HighlightManager.d.ts → HighlightManager.d.ts} +2 -2
- package/dist/{esm/MCMap.d.ts → MCMap.d.ts} +1 -1
- package/dist/{esm/PopupManager.d.ts → PopupManager.d.ts} +4 -4
- package/dist/{esm/Registry.d.ts → Registry.d.ts} +3 -3
- package/dist/{esm/adornments → adornments}/categoricalLegend.d.ts +1 -1
- package/dist/{esm/adornments → adornments}/connectedLegend.d.ts +2 -2
- package/dist/{esm/adornments → adornments}/customAdornment.d.ts +1 -1
- package/dist/{esm/adornments → adornments}/heading.d.ts +1 -1
- package/dist/adornments/insetMap.d.ts +3 -0
- package/dist/{esm/adornments → adornments}/manualLegend.d.ts +1 -1
- package/dist/adornments/northArrow.d.ts +3 -0
- package/dist/adornments/scalebar.d.ts +3 -0
- package/dist/{esm/constants → constants}/index.d.ts +2 -2
- package/dist/{esm/controls → controls}/fullscreenControls.d.ts +1 -1
- package/dist/{esm/controls → controls}/geocoderControl.d.ts +1 -1
- package/dist/{esm/controls → controls}/geolocationControls.d.ts +1 -1
- package/dist/controls/refreshMapControls.d.ts +3 -0
- package/dist/controls/webControls.d.ts +4 -0
- package/dist/{esm/controls → controls}/zoomControls.d.ts +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/locales/da_DK/strings.json.d.ts +10 -0
- package/dist/locales/de_DE/strings.json.d.ts +10 -0
- package/dist/locales/en_GB/strings.json.d.ts +10 -0
- package/dist/locales/es_ES/strings.json.d.ts +10 -0
- package/dist/locales/fr_FR/strings.json.d.ts +10 -0
- package/dist/locales/it_IT/strings.json.d.ts +10 -0
- package/dist/locales/nl_NL/strings.json.d.ts +10 -0
- package/dist/mapcreator-sdk.js +39590 -0
- package/dist/models/area.d.ts +5 -0
- package/dist/models/circle.d.ts +5 -0
- package/dist/models/dot.d.ts +3 -0
- package/dist/models/line.d.ts +4 -0
- package/dist/models/marker.d.ts +5 -0
- package/dist/models/polygon.d.ts +5 -0
- package/dist/{esm/renderAdornments.d.ts → renderAdornments.d.ts} +3 -3
- package/dist/{esm/types → types}/index.d.ts +1 -1
- package/dist/{esm/types → types}/mapstyle.d.ts +2 -6
- package/dist/{esm/utils → utils}/choropleth.d.ts +3 -3
- package/dist/{esm/utils → utils}/geolocation.d.ts +1 -1
- package/dist/{esm/utils → utils}/graphhopper.d.ts +1 -1
- package/dist/{esm/utils → utils}/helpers.d.ts +2 -2
- package/dist/{esm/utils → utils}/language.d.ts +1 -1
- package/dist/{esm/utils → utils}/models.d.ts +4 -4
- package/dist/{esm/utils → utils}/overlays.d.ts +1 -1
- package/dist/{esm/utils → utils}/svgHelpers.d.ts +3 -4
- package/dist/{esm/utils → utils}/template.d.ts +2 -2
- package/dist/{esm/utils → utils}/youtube.d.ts +1 -1
- package/package.json +7 -6
- package/dist/esm/HighlightManager.js +0 -203
- package/dist/esm/MCMap.js +0 -254
- package/dist/esm/PopupManager.js +0 -297
- package/dist/esm/Registry.js +0 -74
- package/dist/esm/adornments/categoricalLegend.js +0 -141
- package/dist/esm/adornments/connectedLegend.js +0 -393
- package/dist/esm/adornments/customAdornment.js +0 -29
- package/dist/esm/adornments/heading.js +0 -71
- package/dist/esm/adornments/insetMap.d.ts +0 -3
- package/dist/esm/adornments/insetMap.js +0 -351
- package/dist/esm/adornments/manualLegend.js +0 -15
- package/dist/esm/adornments/northArrow.d.ts +0 -3
- package/dist/esm/adornments/northArrow.js +0 -24
- package/dist/esm/adornments/scalebar.d.ts +0 -3
- package/dist/esm/adornments/scalebar.js +0 -176
- package/dist/esm/constants/index.js +0 -53
- package/dist/esm/controls/controls.js +0 -7
- package/dist/esm/controls/fullscreenControls.js +0 -29
- package/dist/esm/controls/geocoderControl.js +0 -202
- package/dist/esm/controls/geolocationControls.js +0 -65
- package/dist/esm/controls/refreshMapControls.d.ts +0 -3
- package/dist/esm/controls/refreshMapControls.js +0 -26
- package/dist/esm/controls/webControls.d.ts +0 -4
- package/dist/esm/controls/webControls.js +0 -40
- package/dist/esm/controls/zoomControls.js +0 -23
- package/dist/esm/i18n.js +0 -21
- package/dist/esm/index.d.ts +0 -5
- package/dist/esm/index.js +0 -5
- package/dist/esm/locales/da_DK/strings.json +0 -7
- package/dist/esm/locales/de_DE/strings.json +0 -7
- package/dist/esm/locales/en_GB/strings.json +0 -7
- package/dist/esm/locales/es_ES/strings.json +0 -7
- package/dist/esm/locales/fr_FR/strings.json +0 -7
- package/dist/esm/locales/it_IT/strings.json +0 -7
- package/dist/esm/locales/nl_NL/strings.json +0 -7
- package/dist/esm/models/area.d.ts +0 -5
- package/dist/esm/models/area.js +0 -165
- package/dist/esm/models/circle.d.ts +0 -5
- package/dist/esm/models/circle.js +0 -110
- package/dist/esm/models/dot.d.ts +0 -3
- package/dist/esm/models/dot.js +0 -42
- package/dist/esm/models/line.d.ts +0 -4
- package/dist/esm/models/line.js +0 -117
- package/dist/esm/models/marker.d.ts +0 -5
- package/dist/esm/models/marker.js +0 -179
- package/dist/esm/models/polygon.d.ts +0 -5
- package/dist/esm/models/polygon.js +0 -80
- package/dist/esm/renderAdornments.js +0 -129
- package/dist/esm/types/geometry.js +0 -1
- package/dist/esm/types/index.js +0 -1
- package/dist/esm/types/jobObject.js +0 -1
- package/dist/esm/types/mapstyle.js +0 -1
- package/dist/esm/utils/browser.js +0 -6
- package/dist/esm/utils/choropleth.js +0 -110
- package/dist/esm/utils/fullscreen.js +0 -40
- package/dist/esm/utils/geolocation.js +0 -93
- package/dist/esm/utils/graphhopper.js +0 -41
- package/dist/esm/utils/helpers.js +0 -116
- package/dist/esm/utils/language.js +0 -170
- package/dist/esm/utils/models.js +0 -103
- package/dist/esm/utils/overlays.js +0 -87
- package/dist/esm/utils/scalebar.js +0 -52
- package/dist/esm/utils/svgHelpers.js +0 -1512
- package/dist/esm/utils/template.js +0 -120
- package/dist/esm/utils/youtube.js +0 -64
- /package/dist/{esm/controls → controls}/controls.d.ts +0 -0
- /package/dist/{esm/i18n.d.ts → i18n.d.ts} +0 -0
- /package/dist/{esm/types → types}/geometry.d.ts +0 -0
- /package/dist/{esm/types → types}/jobObject.d.ts +0 -0
- /package/dist/{esm/utils → utils}/browser.d.ts +0 -0
- /package/dist/{esm/utils → utils}/fullscreen.d.ts +0 -0
- /package/dist/{esm/utils → utils}/scalebar.d.ts +0 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { SvgCache } from '../utils/svgHelpers';
|
|
2
|
+
import { JobObjectAreaGroup } from '../types/jobObject';
|
|
3
|
+
import { Map as MapLibre } from '@mapcreator/maplibre-gl';
|
|
4
|
+
import { Svgs } from '../types';
|
|
5
|
+
export declare function addAreaGroup(map: MapLibre, group: JobObjectAreaGroup, beforeId: string, svgs: Svgs, svgCache: SvgCache, vectorUrl: string, accessToken: string): void;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { SvgCache } from '../utils/svgHelpers';
|
|
2
|
+
import { JobObjectCircleGroup } from '../types/jobObject';
|
|
3
|
+
import { Svgs } from '../types';
|
|
4
|
+
import { Map } from '@mapcreator/maplibre-gl';
|
|
5
|
+
export declare function addCircleGroup(map: Map, group: JobObjectCircleGroup, beforeId: string, svgs: Svgs, svgCache: SvgCache): void;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { SvgCache } from '../utils/svgHelpers';
|
|
2
|
+
import { JobObjectLineGroup } from '../types/jobObject';
|
|
3
|
+
import { Map } from '@mapcreator/maplibre-gl';
|
|
4
|
+
export declare function addLineGroup(map: Map, group: JobObjectLineGroup, beforeId: string, svgCache: SvgCache): void;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { SvgCache } from '../utils/svgHelpers';
|
|
2
|
+
import { JobObjectMarkerGroup } from '../types/jobObject';
|
|
3
|
+
import { Map } from '@mapcreator/maplibre-gl';
|
|
4
|
+
import { Svgs } from '../types';
|
|
5
|
+
export declare function addMarkerGroup(map: Map, group: JobObjectMarkerGroup, beforeId: string, svgs: Svgs, svgCache: SvgCache): void;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { SvgCache } from '../utils/svgHelpers';
|
|
2
|
+
import { JobObjectPolygonGroup } from '../types/jobObject';
|
|
3
|
+
import { Map } from '@mapcreator/maplibre-gl';
|
|
4
|
+
import { Svgs } from '../types';
|
|
5
|
+
export declare function addPolygonGroup(map: Map, group: JobObjectPolygonGroup, beforeId: string, svgs: Svgs, svgCache: SvgCache): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import { PositionOffsets, JobObject } from './types/jobObject';
|
|
2
|
+
import { Map as MapLibre } from '@mapcreator/maplibre-gl';
|
|
3
|
+
import { InitialPositionInfo } from './types';
|
|
4
4
|
export declare function useRenderAdornments(jobObject: JobObject, positionOffsets: PositionOffsets | undefined, map: MapLibre, initialPosition: InitialPositionInfo, vapiUrl: string, cdnUrl: string, accessToken: string): void;
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* TODO: consider extracting into a separate package
|
|
4
|
-
*/
|
|
5
|
-
import type { JobObjectModelType } from '@/types/jobObject';
|
|
6
|
-
import type { LayerSpecification } from '@mapcreator/maplibre-gl';
|
|
1
|
+
import { JobObjectModelType } from './jobObject';
|
|
2
|
+
import { LayerSpecification } from '@mapcreator/maplibre-gl';
|
|
7
3
|
export type Anchor = 'center' | 'left' | 'right' | 'top' | 'bottom' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
8
4
|
export type Justify = 'left' | 'center' | 'right';
|
|
9
5
|
export interface LabelStylePreset {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import { ScaleLinear, ScaleOrdinal, ScaleQuantile, ScaleQuantize } from 'd3-scale';
|
|
2
|
+
import { CategoricalGroup, JobObjectAreaGroup } from '../types/jobObject';
|
|
3
|
+
import { ModelBindings } from '../types';
|
|
4
4
|
export type ColorGenerator = ScaleLinear<string, string> | ScaleQuantile<string> | ScaleQuantize<string> | ScaleOrdinal<string, string>;
|
|
5
5
|
export declare const legendTickCount = 4;
|
|
6
6
|
export declare function getColorGenerator(group: JobObjectAreaGroup): ColorGenerator | undefined;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Map } from '@mapcreator/maplibre-gl';
|
|
2
2
|
export declare const loadLocationDot: (map: Map) => void;
|
|
3
3
|
export declare const initLayersAndSources: (map: Map) => void;
|
|
4
4
|
export declare const addLocationDot: (map: any, lng: number, lat: number) => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { LngLat } from '../types/geometry';
|
|
2
2
|
export declare class GraphHopperGeocoderService {
|
|
3
3
|
getLocationInBounds(location: string, center: LngLat, limit?: number): Promise<any>;
|
|
4
4
|
_callGraphHopper(params: any): Promise<any>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { JobObjectDataBindings, JobObjectStoredValue } from '../types/jobObject';
|
|
2
|
+
import { LngLat } from '../types/geometry';
|
|
3
3
|
export declare const numberRe: RegExp;
|
|
4
4
|
export declare function degToRad(angle: number): number;
|
|
5
5
|
export declare function radToDeg(angle: number): number;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
1
|
+
import { LngLat, Position } from '../types/geometry';
|
|
2
|
+
import { JobObjectPolygon } from '../types/jobObject';
|
|
3
|
+
import { ModelBindings } from '../types';
|
|
4
|
+
import { 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[][];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { 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>;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import '
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import type { ColorGenerator } from '@/utils/choropleth';
|
|
1
|
+
import { JobObjectDataBindings } from '../types/jobObject';
|
|
2
|
+
import { Map as MapLibre } from '@mapcreator/maplibre-gl';
|
|
3
|
+
import { ColorGenerator } from './choropleth';
|
|
5
4
|
export declare function escapeXML(str: string): string;
|
|
6
5
|
export declare function loadFonts(fontNames: string[], vapiUrl: string, accessToken: string): Promise<void>;
|
|
7
6
|
export interface SvgColor {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { Mode } from '../types';
|
|
2
|
+
import { JobObjectDataBindings, PopupMedia } from '../types/jobObject';
|
|
3
3
|
export declare function buildTemplate(template: string | undefined, popupMedia: PopupMedia | undefined, bindings: JobObjectDataBindings, mode: Mode): string;
|
|
4
4
|
export declare const closeButtonHtml: string;
|
|
5
5
|
export declare const cycleButtonsHtml: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { PopupMedia, JobObjectDataBindings } from '../types/jobObject';
|
|
2
2
|
export declare function getEmbedUrlFromYoutubeUrl(popupmedia: Extract<PopupMedia, {
|
|
3
3
|
type: 'video';
|
|
4
4
|
}>, bindings: JobObjectDataBindings): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mapcreator/sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": "^24.0.0",
|
|
6
6
|
"npm": "^11.0.0"
|
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
"type": "module",
|
|
10
10
|
"main": "./dist/mapcreator-sdk.umd.cjs",
|
|
11
11
|
"module": "./dist/mapcreator-sdk.js",
|
|
12
|
-
"types": "./dist/
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
13
|
"exports": {
|
|
14
14
|
".": {
|
|
15
|
-
"import": "./dist/
|
|
15
|
+
"import": "./dist/mapcreator-sdk.js",
|
|
16
16
|
"require": "./dist/mapcreator-sdk.umd.cjs",
|
|
17
|
-
"types": "./dist/
|
|
17
|
+
"types": "./dist/index.d.ts"
|
|
18
18
|
},
|
|
19
19
|
"./dist/": {
|
|
20
20
|
"import": "./dist/",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"scripts": {
|
|
25
25
|
"dev": "vite",
|
|
26
|
-
"build": "tsc && vite build
|
|
26
|
+
"build": "tsc && vite build",
|
|
27
27
|
"prettier": "prettier --check src/",
|
|
28
28
|
"prettier:fix": "prettier --write src/",
|
|
29
29
|
"types": "tsc",
|
|
@@ -52,7 +52,8 @@
|
|
|
52
52
|
"prettier": "^3.8.1",
|
|
53
53
|
"rollup-plugin-visualizer": "^7.0.1",
|
|
54
54
|
"typescript": "^5.9.3",
|
|
55
|
-
"vite": "^8.0.1"
|
|
55
|
+
"vite": "^8.0.1",
|
|
56
|
+
"vite-plugin-dts": "^4.5.4"
|
|
56
57
|
},
|
|
57
58
|
"dependencies": {
|
|
58
59
|
"@mapcreator/maplibre-gl": "5.7.0-mc.5",
|
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
import { LngLatBounds } from '@mapcreator/maplibre-gl';
|
|
2
|
-
import { calculateCircle } from '@/utils/models';
|
|
3
|
-
import { stringToId } from '@/utils/helpers';
|
|
4
|
-
export class HighlightManager {
|
|
5
|
-
map;
|
|
6
|
-
popupElements;
|
|
7
|
-
markerLayerIds;
|
|
8
|
-
resizeObserver;
|
|
9
|
-
constructor(map, popupElements) {
|
|
10
|
-
this.map = map;
|
|
11
|
-
this.popupElements = popupElements;
|
|
12
|
-
this.markerLayerIds = this.map
|
|
13
|
-
.getStyle()
|
|
14
|
-
.layers.filter(layer => layer.id.startsWith('custom-marker'))
|
|
15
|
-
.filter(layer => !layer.id.endsWith('-cluster'))
|
|
16
|
-
.map(layer => layer.id);
|
|
17
|
-
}
|
|
18
|
-
highlight(popupElement) {
|
|
19
|
-
this.deselect();
|
|
20
|
-
if (!popupElement) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
const { groupId, modelId } = popupElement;
|
|
24
|
-
const groupedPopups = this.popupElements.filter(item => item.groupId === groupId);
|
|
25
|
-
if (groupedPopups.length > 1 && groupId.startsWith('custom-marker')) {
|
|
26
|
-
this.highlightGroupedMarker(groupId, modelId, groupedPopups);
|
|
27
|
-
}
|
|
28
|
-
if (groupId.startsWith('custom-marker')) {
|
|
29
|
-
this.fadeOtherMarkers(groupId);
|
|
30
|
-
}
|
|
31
|
-
this.repositionMap(popupElement);
|
|
32
|
-
}
|
|
33
|
-
deselect() {
|
|
34
|
-
this.markerLayerIds.forEach(id => {
|
|
35
|
-
this.map.setPaintProperty(id, 'icon-opacity', 1);
|
|
36
|
-
this.map.setPaintProperty(id, 'text-opacity', 1);
|
|
37
|
-
});
|
|
38
|
-
this.resizeObserver?.disconnect();
|
|
39
|
-
}
|
|
40
|
-
highlightGroupedMarker(groupId, modelId, groupedPopups) {
|
|
41
|
-
const groupLayer = this.markerLayerIds.find(id => id.startsWith(groupId));
|
|
42
|
-
if (groupLayer) {
|
|
43
|
-
this.map.setPaintProperty(groupLayer, 'icon-opacity', [
|
|
44
|
-
'case',
|
|
45
|
-
['boolean', ['feature-state', 'highlighted'], false],
|
|
46
|
-
1,
|
|
47
|
-
0.3,
|
|
48
|
-
]);
|
|
49
|
-
this.map.setPaintProperty(groupLayer, 'text-opacity', [
|
|
50
|
-
'case',
|
|
51
|
-
['boolean', ['feature-state', 'highlighted'], false],
|
|
52
|
-
1,
|
|
53
|
-
0.3,
|
|
54
|
-
]);
|
|
55
|
-
groupedPopups.forEach(item => {
|
|
56
|
-
this.map.setFeatureState({ source: groupId, id: stringToId(item.modelId) }, { highlighted: item.modelId === modelId });
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
fadeOtherMarkers(layerId) {
|
|
61
|
-
const otherMarkerIds = this.markerLayerIds.filter(id => !id.startsWith(layerId));
|
|
62
|
-
otherMarkerIds.forEach(id => {
|
|
63
|
-
this.map.setPaintProperty(id, 'icon-opacity', 0.3);
|
|
64
|
-
this.map.setPaintProperty(id, 'text-opacity', 0.3);
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
repositionMap(popupElement) {
|
|
68
|
-
let elementBounds;
|
|
69
|
-
let padding = 20;
|
|
70
|
-
if (popupElement.lngLat !== undefined) {
|
|
71
|
-
elementBounds = new LngLatBounds(popupElement.lngLat, popupElement.lngLat);
|
|
72
|
-
padding = 40;
|
|
73
|
-
}
|
|
74
|
-
else if (popupElement.anchorPoints !== undefined) {
|
|
75
|
-
elementBounds = this.getElementBounds(this.flattenCoordinates(popupElement.anchorPoints));
|
|
76
|
-
}
|
|
77
|
-
else if (popupElement.center !== undefined && popupElement.radius !== undefined) {
|
|
78
|
-
elementBounds = this.getElementBounds(calculateCircle(popupElement.center, popupElement.radius));
|
|
79
|
-
}
|
|
80
|
-
const popupEl = document.querySelector('.popup-container');
|
|
81
|
-
if (!popupEl || !elementBounds) {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
this.resizeObserver?.disconnect();
|
|
85
|
-
let lastHeight = 0;
|
|
86
|
-
this.resizeObserver = new ResizeObserver(entries => {
|
|
87
|
-
const height = entries[0].contentRect.height;
|
|
88
|
-
if (height > lastHeight) {
|
|
89
|
-
lastHeight = height;
|
|
90
|
-
this.panToElement(elementBounds, padding);
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
this.resizeObserver.observe(popupEl);
|
|
94
|
-
}
|
|
95
|
-
getElementBounds(coords) {
|
|
96
|
-
const bounds = new LngLatBounds(coords[0], coords[0]);
|
|
97
|
-
for (const coord of coords) {
|
|
98
|
-
bounds.extend(coord);
|
|
99
|
-
}
|
|
100
|
-
return bounds;
|
|
101
|
-
}
|
|
102
|
-
flattenCoordinates(coords) {
|
|
103
|
-
if (Array.isArray(coords[0][0])) {
|
|
104
|
-
return coords.flat();
|
|
105
|
-
}
|
|
106
|
-
return coords;
|
|
107
|
-
}
|
|
108
|
-
panToElement(elementBounds, padding) {
|
|
109
|
-
const map = this.map;
|
|
110
|
-
const projection = map.getProjection();
|
|
111
|
-
if (projection?.type === 'globe') {
|
|
112
|
-
const testCoords = [
|
|
113
|
-
elementBounds.getSouthWest(),
|
|
114
|
-
elementBounds.getNorthEast(),
|
|
115
|
-
elementBounds.getNorthWest(),
|
|
116
|
-
elementBounds.getSouthEast(),
|
|
117
|
-
];
|
|
118
|
-
const behindGlobe = testCoords.some(c => !this.visibleOnGlobe(c.lng, c.lat));
|
|
119
|
-
if (behindGlobe) {
|
|
120
|
-
map.easeTo({ center: elementBounds.getCenter(), duration: 500 });
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
const sw = map.projectWithScaleCorrection(elementBounds.getSouthWest());
|
|
125
|
-
const ne = map.projectWithScaleCorrection(elementBounds.getNorthEast());
|
|
126
|
-
const mapWidth = map.getContainer().clientWidth;
|
|
127
|
-
const mapHeight = map.getContainer().clientHeight;
|
|
128
|
-
const isDesktop = mapWidth > 600;
|
|
129
|
-
const popupRect = document.querySelector('.popup-container')?.getBoundingClientRect();
|
|
130
|
-
const popupWidth = popupRect?.width ?? 0;
|
|
131
|
-
let popupHeight = popupRect?.height ?? 0;
|
|
132
|
-
if (!isDesktop) {
|
|
133
|
-
popupHeight = Math.min(popupHeight, mapHeight / 2);
|
|
134
|
-
}
|
|
135
|
-
const abovePopup = mapHeight - sw.y > popupHeight + padding;
|
|
136
|
-
const leftVisible = sw.x > padding + (isDesktop && !abovePopup ? popupWidth : 0);
|
|
137
|
-
const rightVisible = ne.x < mapWidth - padding;
|
|
138
|
-
const topVisible = ne.y > padding;
|
|
139
|
-
const bottomVisible = isDesktop ? sw.y < mapHeight - padding : abovePopup;
|
|
140
|
-
if (!(leftVisible && rightVisible && topVisible && bottomVisible)) {
|
|
141
|
-
if (ne.x - sw.x + 2 * padding < mapWidth && sw.y - ne.y + 2 * padding < mapHeight) {
|
|
142
|
-
const center = elementBounds.getCenter();
|
|
143
|
-
map.easeTo({ center, duration: 500, offset: isDesktop ? [0, 0] : [0, -30] });
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
map.fitBounds(elementBounds, {
|
|
147
|
-
padding,
|
|
148
|
-
maxZoom: map.getZoom(),
|
|
149
|
-
duration: 500,
|
|
150
|
-
linear: true,
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
visibleOnGlobe(lng, lat) {
|
|
156
|
-
const { lng: centerLng, lat: centerLat } = this.map.getCenter();
|
|
157
|
-
const pitch = (this.map.getPitch() * Math.PI) / 180;
|
|
158
|
-
const bearing = (this.map.getBearing() * Math.PI) / 180;
|
|
159
|
-
const centerVector = this.lngLatToUnitVector(centerLng, centerLat);
|
|
160
|
-
const featureVector = this.lngLatToUnitVector(lng, lat);
|
|
161
|
-
const up = [0, 0, 1];
|
|
162
|
-
const east = this.normalize(this.cross(up, centerVector));
|
|
163
|
-
const rotationAxis = this.rotateAroundZ(east, bearing);
|
|
164
|
-
const visibleVector = this.rotateVectorAroundAxis(centerVector, rotationAxis, pitch);
|
|
165
|
-
const dot = visibleVector[0] * featureVector[0] +
|
|
166
|
-
visibleVector[1] * featureVector[1] +
|
|
167
|
-
visibleVector[2] * featureVector[2];
|
|
168
|
-
return dot > 0.3;
|
|
169
|
-
}
|
|
170
|
-
lngLatToUnitVector(lng, lat) {
|
|
171
|
-
const a = (lat * Math.PI) / 180;
|
|
172
|
-
const b = (lng * Math.PI) / 180;
|
|
173
|
-
return [Math.cos(a) * Math.cos(b), Math.cos(a) * Math.sin(b), Math.sin(a)];
|
|
174
|
-
}
|
|
175
|
-
rotateVectorAroundAxis(vector, axis, pitch) {
|
|
176
|
-
const [v0, v1, v2] = vector;
|
|
177
|
-
const [a0, a1, a2] = axis;
|
|
178
|
-
const cos = Math.cos(pitch);
|
|
179
|
-
const sin = Math.sin(pitch);
|
|
180
|
-
const dot = v0 * a0 + v1 * a1 + v2 * a2;
|
|
181
|
-
return [
|
|
182
|
-
v0 * cos + (a1 * v2 - a2 * v1) * sin + a0 * dot * (1 - cos),
|
|
183
|
-
v1 * cos + (a2 * v0 - a0 * v2) * sin + a1 * dot * (1 - cos),
|
|
184
|
-
v2 * cos + (a0 * v1 - a1 * v0) * sin + a2 * dot * (1 - cos),
|
|
185
|
-
];
|
|
186
|
-
}
|
|
187
|
-
rotateAroundZ(vector, bearing) {
|
|
188
|
-
const [v0, v1, v2] = vector;
|
|
189
|
-
const cos = Math.cos(bearing);
|
|
190
|
-
const sin = Math.sin(bearing);
|
|
191
|
-
return [v0 * cos - v1 * sin, v0 * sin + v1 * cos, v2];
|
|
192
|
-
}
|
|
193
|
-
cross(vectorA, vectorB) {
|
|
194
|
-
const [a0, a1, a2] = vectorA;
|
|
195
|
-
const [b0, b1, b2] = vectorB;
|
|
196
|
-
return [a1 * b2 - a2 * b1, a2 * b0 - a0 * b2, a0 * b1 - a1 * b0];
|
|
197
|
-
}
|
|
198
|
-
normalize(vector) {
|
|
199
|
-
const [v0, v1, v2] = vector;
|
|
200
|
-
const len = Math.hypot(v0, v1, v2);
|
|
201
|
-
return [v0 / len, v1 / len, v2 / len];
|
|
202
|
-
}
|
|
203
|
-
}
|
package/dist/esm/MCMap.js
DELETED
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
import { LanguageNotation, setLanguage, transformLanguageCode } from '@/utils/language';
|
|
2
|
-
import { AttributionControl, Map as MapLibre } from '@mapcreator/maplibre-gl';
|
|
3
|
-
import { useRenderAdornments } from '@/renderAdornments';
|
|
4
|
-
import { addPolygonGroup } from '@/models/polygon';
|
|
5
|
-
import { addCircleGroup } from '@/models/circle';
|
|
6
|
-
import { addMarkerGroup } from '@/models/marker';
|
|
7
|
-
import { loadOverlays } from '@/utils/overlays';
|
|
8
|
-
import { PopupManager } from '@/PopupManager';
|
|
9
|
-
import { unitConvert } from '@/utils/helpers';
|
|
10
|
-
import { SvgCache } from '@/utils/svgHelpers';
|
|
11
|
-
import { addLineGroup } from '@/models/line';
|
|
12
|
-
import { addAreaGroup } from '@/models/area';
|
|
13
|
-
import { addDotGroup } from '@/models/dot';
|
|
14
|
-
import { defaultSky } from '@/constants';
|
|
15
|
-
import { t } from '@/i18n';
|
|
16
|
-
export class MCMap {
|
|
17
|
-
map;
|
|
18
|
-
constructor(map) {
|
|
19
|
-
this.map = map;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
export async function initMap(options) {
|
|
23
|
-
const { accessToken, mode = 'sdk', env = 'production' } = options;
|
|
24
|
-
const vapiUrl = env === 'bleeding'
|
|
25
|
-
? 'https://vapi.bleeding.mc-cdn.io'
|
|
26
|
-
: env === 'beta'
|
|
27
|
-
? 'https://vapi.beta.mc-cdn.io'
|
|
28
|
-
: 'https://vapi.mc-cdn.io';
|
|
29
|
-
const cdnUrl = env === 'bleeding'
|
|
30
|
-
? 'https://cdn.bleeding.mapcreator.io'
|
|
31
|
-
: env === 'beta'
|
|
32
|
-
? 'https://cdn.beta.mapcreator.io'
|
|
33
|
-
: 'https://cdn.mapcreator.io';
|
|
34
|
-
const jobObject = typeof options.job === 'string'
|
|
35
|
-
? await loadJobObject(options.job, cdnUrl, accessToken)
|
|
36
|
-
: options.job;
|
|
37
|
-
await nonZeroWindowSize();
|
|
38
|
-
const map = new MapLibre({
|
|
39
|
-
container: options.container,
|
|
40
|
-
attributionControl: false,
|
|
41
|
-
style: null,
|
|
42
|
-
maxBounds: [-Infinity, -90, Infinity, 90],
|
|
43
|
-
maxPitch: 85,
|
|
44
|
-
maxZoom: 22,
|
|
45
|
-
locale: {
|
|
46
|
-
'CooperativeGesturesHandler.WindowsHelpText': t('windowsHelpText'),
|
|
47
|
-
'CooperativeGesturesHandler.MacHelpText': t('macHelpText'),
|
|
48
|
-
'CooperativeGesturesHandler.MobileHelpText': t('mobileHelpText'),
|
|
49
|
-
},
|
|
50
|
-
});
|
|
51
|
-
const container = map.getContainer();
|
|
52
|
-
container.classList.add('mc-map');
|
|
53
|
-
const svgCache = new SvgCache(map);
|
|
54
|
-
const popupManager = new PopupManager(map, mode);
|
|
55
|
-
const { map: { language, zoom, pitch = 0, rotation = 0, center, hideBasemap, layerInfo = [], detailLevel = 0, projection = 'mercator', terrain = false, terrainExaggeration = 1, }, export: exportData, registry = {}, web, positionOffsets, title, } = jobObject;
|
|
56
|
-
const { models = {}, slots = {}, svgs = {} } = registry;
|
|
57
|
-
loadFontFaces(env, vapiUrl, accessToken);
|
|
58
|
-
map.resize();
|
|
59
|
-
if (mode === 'app') {
|
|
60
|
-
document.title = title ? `${title} - Mapcreator` : 'Mapcreator';
|
|
61
|
-
}
|
|
62
|
-
map.setPitch(pitch);
|
|
63
|
-
map.setBearing(rotation);
|
|
64
|
-
const unit = exportData?.unit ?? 'pixel';
|
|
65
|
-
const aspectBoxWidth = unitConvert(unit, 'pixel', exportData?.size?.[0] ?? 600);
|
|
66
|
-
const aspectBoxHeight = unitConvert(unit, 'pixel', exportData?.size?.[1] ?? 400);
|
|
67
|
-
let zoomCorrection = 0;
|
|
68
|
-
// Adjust map's zoom level to preserve viewport regardless of map size
|
|
69
|
-
if (container.clientWidth > 0 && container.clientHeight > 0) {
|
|
70
|
-
const scale = Math.min(container.clientWidth / aspectBoxWidth, container.clientHeight / aspectBoxHeight);
|
|
71
|
-
zoomCorrection = Math.log(scale) / Math.LN2;
|
|
72
|
-
}
|
|
73
|
-
map.setZoom(zoom - detailLevel + zoomCorrection);
|
|
74
|
-
map.setCenter(center);
|
|
75
|
-
map.setDetailLevel(detailLevel);
|
|
76
|
-
map.setMinZoom(detailLevel);
|
|
77
|
-
map.addControl(new AttributionControl({ compact: false }));
|
|
78
|
-
if (mode === 'app') {
|
|
79
|
-
map.cooperativeGestures.enable();
|
|
80
|
-
}
|
|
81
|
-
useRenderAdornments(jobObject, positionOffsets, map, {
|
|
82
|
-
center,
|
|
83
|
-
zoom,
|
|
84
|
-
pitch,
|
|
85
|
-
rotation,
|
|
86
|
-
detailLevel,
|
|
87
|
-
width: aspectBoxWidth,
|
|
88
|
-
height: aspectBoxHeight,
|
|
89
|
-
}, vapiUrl, cdnUrl, accessToken);
|
|
90
|
-
popupManager.setJobObject(jobObject);
|
|
91
|
-
if (web) {
|
|
92
|
-
const { restrictMapMovement, popupPosition } = web;
|
|
93
|
-
if (restrictMapMovement) {
|
|
94
|
-
map.boxZoom.disable();
|
|
95
|
-
map.doubleClickZoom.disable();
|
|
96
|
-
map.dragPan.disable();
|
|
97
|
-
map.dragRotate.disable();
|
|
98
|
-
map.keyboard.disable();
|
|
99
|
-
map.scrollZoom.disable();
|
|
100
|
-
map.touchPitch.disable();
|
|
101
|
-
map.touchZoomRotate.disable();
|
|
102
|
-
}
|
|
103
|
-
popupManager.setParams(popupPosition, transformLanguageCode(language, LanguageNotation.TWO), restrictMapMovement, center);
|
|
104
|
-
}
|
|
105
|
-
const mapstyle = await fetch(`${vapiUrl}/styles/${jobObject.meta.mapstyleSet}.json?access_token=${accessToken}`).then(response => response.json());
|
|
106
|
-
map.setStyle(null);
|
|
107
|
-
map.setStyle(mapstyle);
|
|
108
|
-
await map.once('style.load');
|
|
109
|
-
if (mode === 'app') {
|
|
110
|
-
setCustomStyle(map.getStyle().metadata?.customCssFilePath, accessToken);
|
|
111
|
-
}
|
|
112
|
-
// Don't wait for overlays and models to set the language as maps on slow internet will otherwise not be translated immediately
|
|
113
|
-
setLanguage(language, map);
|
|
114
|
-
await loadOverlays(jobObject.meta.layers ?? [], map, vapiUrl, accessToken, mapstyle.metadata?.styleOverride);
|
|
115
|
-
addModels(map, svgCache, models, slots, svgs, vapiUrl, accessToken);
|
|
116
|
-
// Set the language again to translate the overlays and models
|
|
117
|
-
setLanguage(language, map);
|
|
118
|
-
popupManager.setPublication(mapstyle.metadata?.publication);
|
|
119
|
-
popupManager.setpopupElements();
|
|
120
|
-
popupManager.setHighlightManager();
|
|
121
|
-
map.setProjection({ type: projection === 'globe' ? 'globe' : 'mercator' });
|
|
122
|
-
setSky(map, projection);
|
|
123
|
-
if (terrain) {
|
|
124
|
-
initTerrain(map, vapiUrl, accessToken, terrainExaggeration);
|
|
125
|
-
}
|
|
126
|
-
setLayerVisibility(map, map.getStyle(), layerInfo, !hideBasemap);
|
|
127
|
-
return new MCMap(map);
|
|
128
|
-
}
|
|
129
|
-
function loadJobObject(id, cdnUrl, accessToken) {
|
|
130
|
-
return fetch(`${cdnUrl}/jobs/${id}.json?access_token=${accessToken}`).then(response => response.json());
|
|
131
|
-
}
|
|
132
|
-
function nonZeroWindowSize() {
|
|
133
|
-
return new Promise(resolve => {
|
|
134
|
-
const checkSize = () => {
|
|
135
|
-
if (window.innerWidth > 0 && window.innerHeight > 0) {
|
|
136
|
-
window.removeEventListener('resize', checkSize);
|
|
137
|
-
resolve();
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
window.addEventListener('resize', checkSize);
|
|
141
|
-
checkSize();
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
function setSky(map, projection) {
|
|
145
|
-
const meta = map.getStyle().metadata ?? {};
|
|
146
|
-
const backgroundColorFlat = meta['mc:background-color'] ?? '#f8f8f8';
|
|
147
|
-
const backgroundColorGlobe = meta['mc:background-color-globe'] ?? '#000000';
|
|
148
|
-
map.getContainer().style.backgroundColor =
|
|
149
|
-
projection === 'globe' ? backgroundColorGlobe : backgroundColorFlat;
|
|
150
|
-
map.setSky(map.getStyle().sky ?? defaultSky);
|
|
151
|
-
map.setLight({ position: [1.15, 210, 45] });
|
|
152
|
-
}
|
|
153
|
-
function initTerrain(map, vapiUrl, accessToken, exaggeration) {
|
|
154
|
-
map.addSource('mc-dem', {
|
|
155
|
-
type: 'raster-dem',
|
|
156
|
-
tiles: [`${vapiUrl}/dataset/jaxa_terrainrgb/{z}/{x}/{y}?access_token=${accessToken}`],
|
|
157
|
-
attribution: '<a href="https://earth.jaxa.jp/en/data/policy" target="_blank">© AW3D30 (JAXA)</a>',
|
|
158
|
-
minzoom: 0,
|
|
159
|
-
maxzoom: 12,
|
|
160
|
-
});
|
|
161
|
-
map.setTerrain({ source: 'mc-dem', exaggeration });
|
|
162
|
-
}
|
|
163
|
-
function loadFontFaces(env, vapiUrl, accessToken) {
|
|
164
|
-
const betaPrefix = env === 'beta' ? 'b-' : '';
|
|
165
|
-
const href = `${vapiUrl}/stylesheets/ff-${betaPrefix}${accessToken}.css?access_token=${accessToken}`;
|
|
166
|
-
const element = document.createElement('link');
|
|
167
|
-
element.setAttribute('rel', 'stylesheet');
|
|
168
|
-
element.setAttribute('href', href);
|
|
169
|
-
element.setAttribute('type', 'text/css');
|
|
170
|
-
// Inserting at the beginning of <head> to avoid redefining existing Roboto fonts
|
|
171
|
-
// See https://mapcreator.atlassian.net/browse/MC-2702
|
|
172
|
-
document.head.insertBefore(element, document.head.firstChild);
|
|
173
|
-
}
|
|
174
|
-
function setCustomStyle(styleOrURL, accessToken) {
|
|
175
|
-
document.getElementById('custom-style')?.remove();
|
|
176
|
-
if (!styleOrURL) {
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
let element;
|
|
180
|
-
if (styleOrURL.startsWith('http')) {
|
|
181
|
-
styleOrURL = `${styleOrURL}?access_token=${accessToken}`;
|
|
182
|
-
element = document.createElement('link');
|
|
183
|
-
element.setAttribute('rel', 'stylesheet');
|
|
184
|
-
element.setAttribute('href', styleOrURL.replace(/https?:/, ''));
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
element = document.createElement('style');
|
|
188
|
-
element.appendChild(document.createTextNode(styleOrURL));
|
|
189
|
-
}
|
|
190
|
-
element.setAttribute('id', 'custom-style');
|
|
191
|
-
element.setAttribute('type', 'text/css');
|
|
192
|
-
document.head.appendChild(element);
|
|
193
|
-
}
|
|
194
|
-
function setLayerVisibility(map, mapstyle, layers, showBasemap) {
|
|
195
|
-
for (const layer of layers) {
|
|
196
|
-
const existingLayer = mapstyle.layers.find(item => layer.id === item.id || layer.id.endsWith(` | ${item.id}`));
|
|
197
|
-
if (existingLayer) {
|
|
198
|
-
map.setLayoutProperty(existingLayer.id, 'visibility', layer.visibility && showBasemap ? 'visible' : 'none');
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
function addModels(map, svgCache, models, slots, svgs, vapiUrl, accessToken) {
|
|
203
|
-
const { beforeNone = [], beforeNames = [], beforeBoundaries = [], beforeWaters = [] } = slots;
|
|
204
|
-
beforeNone.forEach(item => {
|
|
205
|
-
addModelsByType(map, svgCache, models, item, svgs, 'mc-before-none', vapiUrl, accessToken);
|
|
206
|
-
});
|
|
207
|
-
beforeNames.forEach(item => {
|
|
208
|
-
addModelsByType(map, svgCache, models, item, svgs, 'mc-before-names', vapiUrl, accessToken);
|
|
209
|
-
});
|
|
210
|
-
beforeBoundaries.forEach(item => {
|
|
211
|
-
addModelsByType(map, svgCache, models, item, svgs, 'mc-before-boundaries', vapiUrl, accessToken);
|
|
212
|
-
});
|
|
213
|
-
beforeWaters.forEach(item => {
|
|
214
|
-
addModelsByType(map, svgCache, models, item, svgs, 'mc-before-waters', vapiUrl, accessToken);
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
function addModelsByType(map, svgCache, models, item, svgs, beforeId, vapiUrl, accessToken) {
|
|
218
|
-
if (item.type === 'marker') {
|
|
219
|
-
const group = models.marker?.find(entry => entry.id === item.groupId);
|
|
220
|
-
if (group) {
|
|
221
|
-
addMarkerGroup(map, group, beforeId, svgs, svgCache);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
else if (item.type === 'polygon') {
|
|
225
|
-
const group = models.polygon?.find(entry => entry.id === item.groupId);
|
|
226
|
-
if (group) {
|
|
227
|
-
addPolygonGroup(map, group, beforeId, svgs, svgCache);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
else if (item.type === 'circle') {
|
|
231
|
-
const group = models.circle?.find(entry => entry.id === item.groupId);
|
|
232
|
-
if (group) {
|
|
233
|
-
addCircleGroup(map, group, beforeId, svgs, svgCache);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
else if (item.type === 'line') {
|
|
237
|
-
const group = models.line?.find(entry => entry.id === item.groupId);
|
|
238
|
-
if (group) {
|
|
239
|
-
addLineGroup(map, group, beforeId, svgCache);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
else if (item.type === 'dot') {
|
|
243
|
-
const group = models.dot?.find(entry => entry.id === item.groupId);
|
|
244
|
-
if (group) {
|
|
245
|
-
addDotGroup(map, group, beforeId);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
else if (item.type === 'area') {
|
|
249
|
-
const group = models.area?.find(entry => entry.id === item.groupId);
|
|
250
|
-
if (group) {
|
|
251
|
-
addAreaGroup(map, group, beforeId, svgs, svgCache, vapiUrl, accessToken);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|