@mapcreator/sdk 0.0.9 → 0.0.11
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/README.md +29 -0
- 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 +8 -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.11",
|
|
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",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"@types/d3-geo": "^3.1.0",
|
|
44
44
|
"@types/d3-interpolate": "^3.0.4",
|
|
45
45
|
"@types/d3-scale": "^4.0.9",
|
|
46
|
+
"@types/node": "^25.5.0",
|
|
46
47
|
"@types/topojson-client": "^3.1.5",
|
|
47
48
|
"@vue/eslint-config-prettier": "^10.2.0",
|
|
48
49
|
"@vue/eslint-config-typescript": "^13.0.0",
|
|
@@ -52,7 +53,8 @@
|
|
|
52
53
|
"prettier": "^3.8.1",
|
|
53
54
|
"rollup-plugin-visualizer": "^7.0.1",
|
|
54
55
|
"typescript": "^5.9.3",
|
|
55
|
-
"vite": "^8.0.1"
|
|
56
|
+
"vite": "^8.0.1",
|
|
57
|
+
"vite-plugin-dts": "^4.5.4"
|
|
56
58
|
},
|
|
57
59
|
"dependencies": {
|
|
58
60
|
"@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
|
-
}
|