map-gl-offline 0.8.9 → 0.9.1
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 +62 -192
- package/dist/idb-offline-sw.js +78 -11
- package/dist/index.d.ts +3 -3
- package/dist/index.esm.js +2062 -811
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +2069 -809
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +2401 -940
- package/dist/index.umd.js.map +1 -1
- package/dist/main.d.ts +3 -0
- package/dist/managers/offlineMapManager/analyticsManagement.d.ts +1 -1
- package/dist/managers/offlineMapManager/base.d.ts +5 -5
- package/dist/managers/offlineMapManager/cleanupManagement.d.ts +6 -1
- package/dist/managers/offlineMapManager/importExportManagement.d.ts +1 -1
- package/dist/managers/offlineMapManager/maintenanceManagement.d.ts +1 -1
- package/dist/managers/offlineMapManager/regionManagement.d.ts +2 -2
- package/dist/managers/offlineMapManager/resourceManagement.d.ts +1 -1
- package/dist/managers/offlineMapManager/styleManagement.d.ts +1 -1
- package/dist/services/analyticsService.d.ts +1 -1
- package/dist/services/cleanupService.d.ts +15 -1
- package/dist/services/fontService.d.ts +1 -1
- package/dist/services/glyphService.d.ts +1 -1
- package/dist/services/importExportService.d.ts +1 -1
- package/dist/services/maintenanceService.d.ts +2 -2
- package/dist/services/modelService.d.ts +3 -1
- package/dist/services/regionService.d.ts +21 -11
- package/dist/services/resourceService.d.ts +2 -2
- package/dist/services/runtimeAssetService.d.ts +12 -0
- package/dist/services/spriteService.d.ts +1 -1
- package/dist/services/styleService.d.ts +14 -1
- package/dist/services/tileService.d.ts +1 -1
- package/dist/sheet/collar.d.ts +34 -0
- package/dist/storage/indexedDbManager.d.ts +1 -1
- package/dist/style.css +2 -2
- package/dist/sw/shared.d.ts +31 -3
- package/dist/types/glyph.d.ts +2 -0
- package/dist/types/import-export.d.ts +5 -0
- package/dist/types/maintenance.d.ts +3 -1
- package/dist/types/model.d.ts +2 -0
- package/dist/types/region.d.ts +29 -2
- package/dist/types/sprite.d.ts +2 -0
- package/dist/types/style.d.ts +4 -0
- package/dist/types/tile.d.ts +15 -0
- package/dist/ui/components/PanelActions.d.ts +1 -1
- package/dist/ui/components/PanelHeader.d.ts +1 -1
- package/dist/ui/components/RegionList.d.ts +1 -1
- package/dist/ui/components/shared/Button.d.ts +6 -0
- package/dist/ui/components/shared/LanguageSelector.d.ts +1 -1
- package/dist/ui/components/shared/MapControlButton.d.ts +1 -1
- package/dist/ui/components/shared/PanelContent.d.ts +3 -3
- package/dist/ui/components/shared/RegionDrawingTool.d.ts +2 -2
- package/dist/ui/controls/polygonControl.d.ts +7 -1
- package/dist/ui/controls/regionControl.d.ts +3 -3
- package/dist/ui/managers/ControlButtonManager.d.ts +1 -1
- package/dist/ui/managers/PanelManager.d.ts +16 -3
- package/dist/ui/managers/downloadManager.d.ts +7 -3
- package/dist/ui/modals/mbtilesModal.d.ts +1 -1
- package/dist/ui/modals/regionDetailsModal.d.ts +1 -1
- package/dist/ui/modals/regionFormModal.d.ts +11 -1
- package/dist/ui/offlineManagerControl.d.ts +4 -1
- package/dist/ui/translations/ar.d.ts +16 -1
- package/dist/ui/translations/en.d.ts +16 -1
- package/dist/ui/translations/index.d.ts +2 -0
- package/dist/utils/constants.d.ts +4 -2
- package/dist/utils/convertStyleForSW.d.ts +1 -1
- package/dist/utils/download.d.ts +1 -1
- package/dist/utils/formatting.d.ts +11 -0
- package/dist/utils/importResolver.d.ts +1 -1
- package/dist/utils/styleConfig.d.ts +39 -0
- package/dist/utils/styleProviderUtils.d.ts +21 -8
- package/dist/utils/styleUtils.d.ts +61 -10
- package/dist/utils/tileRange.d.ts +63 -0
- package/dist/utils/validation.d.ts +1 -1
- package/package.json +44 -39
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Handles polygon drawing, area calculation, and map visualization
|
|
4
4
|
*/
|
|
5
5
|
import type { Map as MaplibreMap } from 'maplibre-gl';
|
|
6
|
-
import type { CssPrefix } from '../../utils/cssPrefix';
|
|
6
|
+
import type { CssPrefix } from '../../utils/cssPrefix.js';
|
|
7
7
|
export interface PolygonControlOptions {
|
|
8
8
|
onSave: (bounds: [number, number, number, number], area: number) => void;
|
|
9
9
|
onCancel: () => void;
|
|
@@ -74,6 +74,12 @@ export declare class PolygonControl {
|
|
|
74
74
|
* Handle map move/zoom events
|
|
75
75
|
*/
|
|
76
76
|
private handleMapMove;
|
|
77
|
+
/**
|
|
78
|
+
* The area to select: the middle of what's on screen. On a tilted or rotated map
|
|
79
|
+
* `getBounds()` reaches far past the view, so insetting it would miss the part
|
|
80
|
+
* nearest the camera. There, measure from the map's centre to the screen's edges.
|
|
81
|
+
*/
|
|
82
|
+
private getSelectionBbox;
|
|
77
83
|
/**
|
|
78
84
|
* Update polygon visualization based on current map bounds
|
|
79
85
|
*/
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
* Manages region selection, form modal, and saves
|
|
4
4
|
*/
|
|
5
5
|
import type { Map as MaplibreMap } from 'maplibre-gl';
|
|
6
|
-
import { DownloadManager } from '
|
|
7
|
-
import { ModalManager } from '
|
|
8
|
-
import type { CssPrefix } from '../../utils/cssPrefix';
|
|
6
|
+
import { DownloadManager } from '../managers/downloadManager.js';
|
|
7
|
+
import { ModalManager } from '../modals/modalManager.js';
|
|
8
|
+
import type { CssPrefix } from '../../utils/cssPrefix.js';
|
|
9
9
|
export interface RegionControlOptions {
|
|
10
10
|
map: MaplibreMap;
|
|
11
11
|
downloadManager: DownloadManager;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Manages the main control button and progress badge states
|
|
4
4
|
* Refactored to use modular Button component
|
|
5
5
|
*/
|
|
6
|
-
import type { CssPrefix } from '../../utils/cssPrefix';
|
|
6
|
+
import type { CssPrefix } from '../../utils/cssPrefix.js';
|
|
7
7
|
export interface ButtonManagerOptions {
|
|
8
8
|
onTogglePanel: () => void;
|
|
9
9
|
cssPrefix?: CssPrefix;
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* Handles rendering of the main offline manager panel
|
|
4
4
|
* Refactored to use modular components
|
|
5
5
|
*/
|
|
6
|
-
import { OfflineMapManager } from '../../managers/offlineMapManager';
|
|
6
|
+
import { OfflineMapManager } from '../../managers/offlineMapManager.js';
|
|
7
7
|
import { DownloadManager } from './downloadManager';
|
|
8
|
-
import { ModalManager } from '
|
|
9
|
-
import { BaseComponent } from '
|
|
8
|
+
import { ModalManager } from '../modals/modalManager.js';
|
|
9
|
+
import { BaseComponent } from '../components/shared/BaseComponent.js';
|
|
10
10
|
type MaplibreMap = unknown;
|
|
11
11
|
export interface PanelRendererOptions {
|
|
12
12
|
offlineManager: OfflineMapManager;
|
|
@@ -31,10 +31,12 @@ export declare class PanelRenderer extends BaseComponent {
|
|
|
31
31
|
private headerContainer?;
|
|
32
32
|
private actionButtonsContainer?;
|
|
33
33
|
private regionsList?;
|
|
34
|
+
private awaitingProgressRender;
|
|
34
35
|
private downloadProgressContainer?;
|
|
35
36
|
private languageSelector?;
|
|
36
37
|
private refreshTimeout?;
|
|
37
38
|
private isRefreshing;
|
|
39
|
+
private refreshQueued;
|
|
38
40
|
private unsubscribeLanguage?;
|
|
39
41
|
private regionActionHandler?;
|
|
40
42
|
constructor(options: PanelRendererOptions);
|
|
@@ -79,6 +81,13 @@ export declare class PanelRenderer extends BaseComponent {
|
|
|
79
81
|
* Create orphaned regions header template
|
|
80
82
|
*/
|
|
81
83
|
private createOrphanedRegionsHeaderTemplate;
|
|
84
|
+
/**
|
|
85
|
+
* Show the latest download progress. Called on every update, so it only
|
|
86
|
+
* redraws the progress section rather than the whole panel.
|
|
87
|
+
*/
|
|
88
|
+
updateDownloadProgress(downloads: ReadonlyMap<string, unknown>): void;
|
|
89
|
+
/** What the current phase is doing, such as "Tiles: 64 of 128". */
|
|
90
|
+
private describeDownloadPhase;
|
|
82
91
|
/**
|
|
83
92
|
* Create download progress HTML
|
|
84
93
|
*/
|
|
@@ -158,6 +167,10 @@ export declare class PanelRenderer extends BaseComponent {
|
|
|
158
167
|
/**
|
|
159
168
|
* Handle loading a style to the map
|
|
160
169
|
*/
|
|
170
|
+
/** Whether the map is drawing this stored style, through `idb://` or the Service Worker. */
|
|
171
|
+
private isStyleShown;
|
|
172
|
+
/** After its stored copy is deleted, show a style from its original URL, not a blank map. */
|
|
173
|
+
private showOnlineStyle;
|
|
161
174
|
private handleLoadStyle;
|
|
162
175
|
/**
|
|
163
176
|
* Handle deleting a style
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
*
|
|
45
45
|
* @module downloadManager
|
|
46
46
|
*/
|
|
47
|
-
import { OfflineMapManager } from '../../managers/offlineMapManager';
|
|
48
|
-
import { RegionFormData } from '
|
|
47
|
+
import { OfflineMapManager } from '../../managers/offlineMapManager.js';
|
|
48
|
+
import { RegionFormData } from '../modals/regionFormModal.js';
|
|
49
49
|
/**
|
|
50
50
|
* Progress information for an active download.
|
|
51
51
|
*
|
|
@@ -70,8 +70,10 @@ export interface DownloadProgress {
|
|
|
70
70
|
completed: number;
|
|
71
71
|
/** Total number of resources in current phase */
|
|
72
72
|
total: number;
|
|
73
|
-
/**
|
|
73
|
+
/** How far through the whole download (0-100). Only moves forward. */
|
|
74
74
|
percentage: number;
|
|
75
|
+
/** How far through the current phase (0-100). */
|
|
76
|
+
phasePercentage?: number;
|
|
75
77
|
/** Human-readable description of current activity */
|
|
76
78
|
currentResource: string;
|
|
77
79
|
/** Current download phase */
|
|
@@ -119,6 +121,8 @@ export declare class DownloadManager {
|
|
|
119
121
|
private offlineManager;
|
|
120
122
|
/** Map of region IDs to their download progress */
|
|
121
123
|
private currentDownloads;
|
|
124
|
+
/** Aborts each running download, by region id. */
|
|
125
|
+
private controllers;
|
|
122
126
|
private options;
|
|
123
127
|
/**
|
|
124
128
|
* Create a new DownloadManager instance.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Focused modal for exchanging regions as binary SQLite MBTiles archives.
|
|
5
5
|
* Replaces the previous multi-format import/export modal.
|
|
6
6
|
*/
|
|
7
|
-
import type { StoredRegion, ImportExportOptions, MBTilesExportOptions, ExportResult, ImportResult, RegionImportData } from '../../types';
|
|
7
|
+
import type { StoredRegion, ImportExportOptions, MBTilesExportOptions, ExportResult, ImportResult, RegionImportData } from '../../types/index.js';
|
|
8
8
|
type MBTilesExportRequestOptions = ImportExportOptions & MBTilesExportOptions;
|
|
9
9
|
export interface MBTilesModalOptions {
|
|
10
10
|
region: StoredRegion;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Shows detailed information about a specific region
|
|
4
4
|
* Refactored to use modular components
|
|
5
5
|
*/
|
|
6
|
-
import { StoredRegion } from '../../types/region';
|
|
6
|
+
import { StoredRegion } from '../../types/region.js';
|
|
7
7
|
export interface RegionDetailsOptions {
|
|
8
8
|
region: StoredRegion;
|
|
9
9
|
onClose: () => void;
|
|
@@ -12,7 +12,7 @@ export interface RegionFormData {
|
|
|
12
12
|
provider?: 'mapbox' | 'maplibre' | 'auto';
|
|
13
13
|
accessToken?: string | null;
|
|
14
14
|
/** Additional tile sources to download alongside the style's own sources */
|
|
15
|
-
extraSources?: import('../../types/region').ExtraSource[];
|
|
15
|
+
extraSources?: import('../../types/region.js').ExtraSource[];
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
18
|
* A tile source discovered on the live map, presented to the user for selection.
|
|
@@ -42,6 +42,11 @@ export interface RegionFormOptions {
|
|
|
42
42
|
/** Tile sources discovered from the live map for user selection */
|
|
43
43
|
mapSources?: MapTileSource[];
|
|
44
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* True when a region of Mapbox Standard stops below the zoom where its buildings
|
|
47
|
+
* start. Standard Satellite has no buildings, so it doesn't count.
|
|
48
|
+
*/
|
|
49
|
+
export declare function regionMissesBuildings(styleUrl: string, maxZoom: number): boolean;
|
|
45
50
|
export declare class RegionFormModal {
|
|
46
51
|
private options;
|
|
47
52
|
private modal?;
|
|
@@ -49,6 +54,7 @@ export declare class RegionFormModal {
|
|
|
49
54
|
private minZoomInput?;
|
|
50
55
|
private maxZoomInput?;
|
|
51
56
|
private styleUrlInput?;
|
|
57
|
+
private buildingsHint?;
|
|
52
58
|
private providerSelect?;
|
|
53
59
|
private accessTokenInput?;
|
|
54
60
|
private accessTokenGroup?;
|
|
@@ -73,6 +79,8 @@ export declare class RegionFormModal {
|
|
|
73
79
|
/**
|
|
74
80
|
* Handle style URL changes to auto-detect provider
|
|
75
81
|
*/
|
|
82
|
+
/** Warn when a region would be saved without the style's buildings. */
|
|
83
|
+
private updateBuildingsHint;
|
|
76
84
|
private handleStyleUrlChange;
|
|
77
85
|
/**
|
|
78
86
|
* Handle provider selection changes
|
|
@@ -90,6 +98,8 @@ export declare class RegionFormModal {
|
|
|
90
98
|
* Create the footer with action buttons
|
|
91
99
|
*/
|
|
92
100
|
private createFooter;
|
|
101
|
+
/** Check the zoom fields, showing the browser's message on the first bad one. */
|
|
102
|
+
private zoomRangeIsValid;
|
|
93
103
|
/**
|
|
94
104
|
* Handle form save
|
|
95
105
|
*/
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
* @module offlineManagerControl
|
|
36
36
|
*/
|
|
37
37
|
import type { IControl } from 'maplibre-gl';
|
|
38
|
-
import { OfflineMapManager } from '../managers/offlineMapManager';
|
|
38
|
+
import { OfflineMapManager } from '../managers/offlineMapManager.js';
|
|
39
39
|
/**
|
|
40
40
|
* Request shape MapLibre passes to a protocol handler. `type` indicates how
|
|
41
41
|
* the response will be consumed — `"json"` for sprite atlases / TileJSON,
|
|
@@ -127,6 +127,9 @@ export declare class OfflineManagerControl implements IControl {
|
|
|
127
127
|
private regionControl;
|
|
128
128
|
private downloadManager;
|
|
129
129
|
private modalManager;
|
|
130
|
+
/** Percentages of this batch's downloads, finished ones at 100, for the badge. */
|
|
131
|
+
private badgeBatch;
|
|
132
|
+
private badgePercentage;
|
|
130
133
|
/** Whether the bounding box visualization layer has been added to the map */
|
|
131
134
|
private bboxLayerAdded;
|
|
132
135
|
/** Map library module for protocol registration (null if not provided) */
|
|
@@ -24,7 +24,7 @@ export declare const ar: {
|
|
|
24
24
|
readonly 'language.en': "الإنجليزية";
|
|
25
25
|
readonly 'language.ar': "العربية";
|
|
26
26
|
readonly 'header.title': "مدير الخرائط غير المتصلة";
|
|
27
|
-
readonly 'header.subtitle': "{{
|
|
27
|
+
readonly 'header.subtitle': "{{regions}} • {{size}} إجمالي";
|
|
28
28
|
readonly 'actions.addRegion': "إضافة منطقة";
|
|
29
29
|
readonly 'actions.refresh': "تحديث";
|
|
30
30
|
readonly 'actions.loadStyle': "تحميل النمط";
|
|
@@ -38,6 +38,8 @@ export declare const ar: {
|
|
|
38
38
|
readonly 'regionForm.namePlaceholder': "مثال: وسط المدينة";
|
|
39
39
|
readonly 'regionForm.minZoom': "أدنى تكبير";
|
|
40
40
|
readonly 'regionForm.maxZoom': "أقصى تكبير";
|
|
41
|
+
readonly 'regionForm.buildingsHint': "تبدأ مباني Mapbox Standard عند مستوى التكبير 15. اضبط أقصى تكبير على 15 أو أكثر لتضمينها.";
|
|
42
|
+
readonly 'regionForm.zoomRangeError': "يجب ألا يقل أقصى تكبير عن أدنى تكبير.";
|
|
41
43
|
readonly 'regionForm.styleUrl': "رابط النمط";
|
|
42
44
|
readonly 'regionForm.provider': "مزود النمط";
|
|
43
45
|
readonly 'regionForm.providerAuto': "اكتشاف تلقائي";
|
|
@@ -66,7 +68,10 @@ export declare const ar: {
|
|
|
66
68
|
readonly 'regionList.downloaded': "تم التحميل";
|
|
67
69
|
readonly 'regionList.size': "الحجم";
|
|
68
70
|
readonly 'regionList.tiles': "البلاطات";
|
|
71
|
+
readonly 'regionList.resources': "الخطوط والرموز والنماذج";
|
|
69
72
|
readonly 'regionList.styleData': "النمط";
|
|
73
|
+
readonly 'regionList.regionCountOne': "منطقة واحدة";
|
|
74
|
+
readonly 'regionList.regionCount': "{{count}} منطقة";
|
|
70
75
|
readonly 'regionList.totalSize': "الإجمالي";
|
|
71
76
|
readonly 'regionList.styleId': "معرف النمط";
|
|
72
77
|
readonly 'regionDetails.title': "تفاصيل المنطقة";
|
|
@@ -138,6 +143,14 @@ export declare const ar: {
|
|
|
138
143
|
readonly 'mbtiles.importComplete': "اكتمل الاستيراد!";
|
|
139
144
|
readonly 'mbtiles.importFailed': "فشل الاستيراد. يرجى المحاولة مرة أخرى.";
|
|
140
145
|
readonly 'download.activeCount': "التحميلات النشطة ({{count}})";
|
|
146
|
+
readonly 'download.status.style': "جارٍ تجهيز النمط";
|
|
147
|
+
readonly 'download.status.sprites': "الرموز: {{completed}} من {{total}}";
|
|
148
|
+
readonly 'download.status.glyphs': "الخطوط: {{completed}} من {{total}}";
|
|
149
|
+
readonly 'download.status.models': "النماذج ثلاثية الأبعاد: {{completed}} من {{total}}";
|
|
150
|
+
readonly 'download.status.tiles': "البلاطات: {{completed}} من {{total}}";
|
|
151
|
+
readonly 'download.status.planning': "جارٍ تخطيط البلاطات";
|
|
152
|
+
readonly 'download.cancelRegion': "إلغاء تحميل {{name}}";
|
|
153
|
+
readonly 'download.status.saving': "جارٍ حفظ المنطقة";
|
|
141
154
|
readonly 'panel.downloadedRegions': "المناطق المحملة";
|
|
142
155
|
readonly 'panel.noExpiry': "بدون انتهاء";
|
|
143
156
|
readonly 'panel.noBounds': "بدون حدود";
|
|
@@ -153,6 +166,8 @@ export declare const ar: {
|
|
|
153
166
|
readonly 'control.cancelSelection': "إلغاء التحديد";
|
|
154
167
|
readonly 'control.saveSelectedRegion': "حفظ المنطقة المحددة";
|
|
155
168
|
readonly 'alert.unknownError': "حدث خطأ غير معروف";
|
|
169
|
+
readonly 'alert.downloadFailed': "فشل التحميل";
|
|
170
|
+
readonly 'alert.needsMapboxGl': "يستخدم هذا النمط ميزات Mapbox GL JS، مثل النماذج ثلاثية الأبعاد أو إعدادات النمط، لذا لا يمكن عرضه إلا على خريطة Mapbox GL.";
|
|
156
171
|
readonly 'alert.downloadNotImplemented': "ميزة التحميل غير مطبقة في هذه النسخة";
|
|
157
172
|
readonly 'alert.mapNotAvailable': "الخريطة غير متاحة";
|
|
158
173
|
readonly 'alert.invalidBounds': "حدود غير صالحة للمنطقة";
|
|
@@ -23,7 +23,7 @@ export declare const en: {
|
|
|
23
23
|
readonly 'language.en': "English";
|
|
24
24
|
readonly 'language.ar': "Arabic";
|
|
25
25
|
readonly 'header.title': "Offline Manager";
|
|
26
|
-
readonly 'header.subtitle': "{{
|
|
26
|
+
readonly 'header.subtitle': "{{regions}} • {{size}} total";
|
|
27
27
|
readonly 'actions.addRegion': "Add Region";
|
|
28
28
|
readonly 'actions.refresh': "Refresh";
|
|
29
29
|
readonly 'actions.loadStyle': "Load Style";
|
|
@@ -37,6 +37,8 @@ export declare const en: {
|
|
|
37
37
|
readonly 'regionForm.namePlaceholder': "e.g., Downtown District";
|
|
38
38
|
readonly 'regionForm.minZoom': "Min Zoom";
|
|
39
39
|
readonly 'regionForm.maxZoom': "Max Zoom";
|
|
40
|
+
readonly 'regionForm.buildingsHint': "Mapbox Standard's buildings start at zoom 15. Set Max Zoom to 15 or more to include them.";
|
|
41
|
+
readonly 'regionForm.zoomRangeError': "Max Zoom must be at least Min Zoom.";
|
|
40
42
|
readonly 'regionForm.styleUrl': "Style URL";
|
|
41
43
|
readonly 'regionForm.provider': "Style Provider";
|
|
42
44
|
readonly 'regionForm.providerAuto': "Auto-detect";
|
|
@@ -65,7 +67,10 @@ export declare const en: {
|
|
|
65
67
|
readonly 'regionList.downloaded': "Downloaded";
|
|
66
68
|
readonly 'regionList.size': "Size";
|
|
67
69
|
readonly 'regionList.tiles': "Tiles";
|
|
70
|
+
readonly 'regionList.resources': "Fonts, icons and models";
|
|
68
71
|
readonly 'regionList.styleData': "Style";
|
|
72
|
+
readonly 'regionList.regionCountOne': "1 region";
|
|
73
|
+
readonly 'regionList.regionCount': "{{count}} regions";
|
|
69
74
|
readonly 'regionList.totalSize': "Total";
|
|
70
75
|
readonly 'regionList.styleId': "Style ID";
|
|
71
76
|
readonly 'regionDetails.title': "Region Details";
|
|
@@ -137,6 +142,14 @@ export declare const en: {
|
|
|
137
142
|
readonly 'mbtiles.importComplete': "Import complete!";
|
|
138
143
|
readonly 'mbtiles.importFailed': "Import failed. Please try again.";
|
|
139
144
|
readonly 'download.activeCount': "Active Downloads ({{count}})";
|
|
145
|
+
readonly 'download.status.style': "Preparing style";
|
|
146
|
+
readonly 'download.status.sprites': "Sprites: {{completed}} of {{total}}";
|
|
147
|
+
readonly 'download.status.glyphs': "Fonts: {{completed}} of {{total}}";
|
|
148
|
+
readonly 'download.status.models': "3D models: {{completed}} of {{total}}";
|
|
149
|
+
readonly 'download.status.tiles': "Tiles: {{completed}} of {{total}}";
|
|
150
|
+
readonly 'download.status.planning': "Planning tiles";
|
|
151
|
+
readonly 'download.cancelRegion': "Cancel downloading {{name}}";
|
|
152
|
+
readonly 'download.status.saving': "Saving region";
|
|
140
153
|
readonly 'panel.downloadedRegions': "Downloaded Regions";
|
|
141
154
|
readonly 'panel.noExpiry': "No expiry";
|
|
142
155
|
readonly 'panel.noBounds': "No bounds";
|
|
@@ -152,6 +165,8 @@ export declare const en: {
|
|
|
152
165
|
readonly 'control.cancelSelection': "Cancel Selection";
|
|
153
166
|
readonly 'control.saveSelectedRegion': "Save Selected Region";
|
|
154
167
|
readonly 'alert.unknownError': "Unknown error occurred";
|
|
168
|
+
readonly 'alert.downloadFailed': "Download failed";
|
|
169
|
+
readonly 'alert.needsMapboxGl': "This style uses Mapbox GL JS features, such as 3D models or style config, so only a Mapbox GL map can show it.";
|
|
155
170
|
readonly 'alert.downloadNotImplemented': "Download feature not implemented in this refactored version";
|
|
156
171
|
readonly 'alert.mapNotAvailable': "Map not available";
|
|
157
172
|
readonly 'alert.invalidBounds': "Invalid bounds for region";
|
|
@@ -57,5 +57,7 @@ declare class I18nManager {
|
|
|
57
57
|
}
|
|
58
58
|
export declare const i18n: I18nManager;
|
|
59
59
|
export declare const t: (key: TranslationKey, replacements?: Record<string, string | number>) => string;
|
|
60
|
+
/** "1 region" or "3 regions", in the current language. */
|
|
61
|
+
export declare const regionCountLabel: (count: number) => string;
|
|
60
62
|
export { i18next };
|
|
61
63
|
export { en, ar };
|
|
@@ -84,8 +84,10 @@ export declare const MAPBOX_API: {
|
|
|
84
84
|
/**
|
|
85
85
|
* Mapbox Standard sub-tilesets that are sparse-by-design across the planet.
|
|
86
86
|
* These only have tiles where the underlying feature (indoor venues, landmark
|
|
87
|
-
* POIs, 3D procedural buildings) actually exists, and return 404 for
|
|
88
|
-
*
|
|
87
|
+
* POIs, 3D procedural buildings) actually exists, and return 404 for every other
|
|
88
|
+
* coordinate, though they can be dense inside a major city. Unless the style's
|
|
89
|
+
* config has switched on a feature that needs one, the tile downloader pre-skips
|
|
90
|
+
* any source whose tile
|
|
89
91
|
* URL templates reference one of these tileset IDs, so we never issue probe
|
|
90
92
|
* or download requests for them — eliminating the 404 noise in devtools.
|
|
91
93
|
*
|
package/dist/utils/download.d.ts
CHANGED
|
@@ -5,6 +5,17 @@
|
|
|
5
5
|
* Format bytes to human readable string
|
|
6
6
|
*/
|
|
7
7
|
export declare function formatBytes(bytes: number): string;
|
|
8
|
+
/**
|
|
9
|
+
* A stored style's display name: its own `name`, or else the last meaningful
|
|
10
|
+
* part of its URL ("liberty" for `.../styles/liberty`), or else its key.
|
|
11
|
+
*/
|
|
12
|
+
export declare function styleDisplayName(entry: {
|
|
13
|
+
key: string;
|
|
14
|
+
originalUrl?: string;
|
|
15
|
+
style?: {
|
|
16
|
+
name?: string;
|
|
17
|
+
};
|
|
18
|
+
}): string;
|
|
8
19
|
/**
|
|
9
20
|
* Format date to human readable string
|
|
10
21
|
*/
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* into the outer style. This allows the existing download pipeline to work
|
|
7
7
|
* unchanged with import-based styles like Mapbox Standard.
|
|
8
8
|
*/
|
|
9
|
-
import type { BaseStyle } from '../types/style';
|
|
9
|
+
import type { BaseStyle } from '../types/style.js';
|
|
10
10
|
/** A single import entry in a style's `imports` array */
|
|
11
11
|
export interface StyleImport {
|
|
12
12
|
id: string;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mapbox GL v3 style-config helpers.
|
|
3
|
+
*
|
|
4
|
+
* Mapbox Standard is one style with switchable features: most of its layers set
|
|
5
|
+
* `layout.visibility` from `["config", key]` expressions backed by `style.schema`
|
|
6
|
+
* defaults. These helpers work out which sources the style actually needs for
|
|
7
|
+
* the current config, so features that are switched off aren't downloaded and
|
|
8
|
+
* features that are switched on aren't skipped.
|
|
9
|
+
*/
|
|
10
|
+
import type { BaseStyle } from '../types/style.js';
|
|
11
|
+
type ConfigValues = Record<string, unknown>;
|
|
12
|
+
/**
|
|
13
|
+
* True for styles whose feature set is config-driven: they declare a `schema`,
|
|
14
|
+
* or were flattened from `imports` (whose config is already resolved into the
|
|
15
|
+
* layers). Other styles are never filtered by config.
|
|
16
|
+
*/
|
|
17
|
+
export declare function isConfigDrivenStyle(style: unknown): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Sources a config-driven style uses under its current config (`active`), and
|
|
20
|
+
* those it references but only from hidden layers or unused iconsets (`inactive`).
|
|
21
|
+
*
|
|
22
|
+
* Deliberately errs towards keeping sources: a visibility expression that can't
|
|
23
|
+
* be decided counts as visible. Sources nothing in the style references
|
|
24
|
+
* (`extraSources`, ones a caller adds at runtime) are in neither set.
|
|
25
|
+
*/
|
|
26
|
+
export declare function classifySources(style: unknown): {
|
|
27
|
+
active: Set<string>;
|
|
28
|
+
inactive: Set<string>;
|
|
29
|
+
};
|
|
30
|
+
/** The sources {@link classifySources} found to be unneeded under the current config. */
|
|
31
|
+
export declare function findInactiveSources(style: unknown): Set<string>;
|
|
32
|
+
/**
|
|
33
|
+
* Write config values into a style's `schema` defaults. `["config", key]` reads
|
|
34
|
+
* those defaults at render time, so this one edit drives both what gets
|
|
35
|
+
* downloaded and what the stored style shows offline. Keys the schema doesn't
|
|
36
|
+
* declare are ignored with a warning.
|
|
37
|
+
*/
|
|
38
|
+
export declare function applyStyleConfig(style: BaseStyle, config: ConfigValues): void;
|
|
39
|
+
export {};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Style Provider Detection and Handling Utilities
|
|
3
3
|
* Supports both Mapbox GL and MapLibre GL styles
|
|
4
4
|
*/
|
|
5
|
-
import type { BaseStyle, StyleProvider } from '../types/style';
|
|
5
|
+
import type { BaseStyle, StyleProvider } from '../types/style.js';
|
|
6
6
|
/**
|
|
7
7
|
* Check if a URL uses the mapbox:// protocol
|
|
8
8
|
*/
|
|
@@ -34,17 +34,30 @@ export declare function isMapboxHost(url: string, base?: string): boolean;
|
|
|
34
34
|
*/
|
|
35
35
|
export declare function resolveMapboxUrl(mapboxUrl: string, accessToken: string): string;
|
|
36
36
|
/**
|
|
37
|
-
*
|
|
37
|
+
* Pick the TileJSON variant Mapbox GL renders from, the way its `mergeVariants`
|
|
38
|
+
* does: `meshopt-v2+lod`, then `meshopt`, then the base tileset.
|
|
38
39
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
40
|
+
* These aren't just different encodings of one dataset. For
|
|
41
|
+
* `mapbox.mapbox-3dbuildings-v1`, the base tile over central Dubai is empty while
|
|
42
|
+
* the variants hold its 3D buildings, so downloading the base loses them offline.
|
|
43
|
+
* Variant tiles are `mapbox://3dtiles/...` URLs, resolved here using the base
|
|
44
|
+
* URL's query string, which carries the access token.
|
|
45
|
+
*/
|
|
46
|
+
export declare function selectTileJsonVariant<T extends object>(tileJson: T): T;
|
|
47
|
+
/**
|
|
48
|
+
* Add the `sku` session token that Mapbox `/raster/v1/` tile URLs need.
|
|
49
|
+
*
|
|
50
|
+
* TileJSON returns these URLs without one, and without it they 401. Mapbox GL
|
|
51
|
+
* adds it at request time, but this library fetches tiles itself.
|
|
52
|
+
*
|
|
53
|
+
* Don't switch these to the `/v4/` endpoint, which needs no token: it serves a
|
|
54
|
+
* different tile. For `mapbox.mapbox-terrain-dem-v1`, `/v4/….png` is a 256px
|
|
55
|
+
* palette PNG with elevations off by up to ~200 m, while the renderer expects
|
|
56
|
+
* the 514px RGB tile (`tileSize: 514`) that `/raster/v1/` returns.
|
|
44
57
|
*
|
|
45
58
|
* Example:
|
|
46
59
|
* https://a.tiles.mapbox.com/raster/v1/mapbox.mapbox-terrain-dem-v1/{z}/{x}/{y}.png?access_token=...
|
|
47
|
-
* -> https://
|
|
60
|
+
* -> https://a.tiles.mapbox.com/raster/v1/mapbox.mapbox-terrain-dem-v1/{z}/{x}/{y}.png?access_token=...&sku=101...
|
|
48
61
|
*/
|
|
49
62
|
export declare function rewriteMapboxCdnTileUrl(tileUrl: string): string;
|
|
50
63
|
/**
|
|
@@ -1,22 +1,72 @@
|
|
|
1
|
-
import type { MapboxStyle } from '../types/style';
|
|
1
|
+
import type { MapboxStyle } from '../types/style.js';
|
|
2
2
|
/**
|
|
3
|
-
* Patches a MapboxStyle for offline use by replacing URLs with IndexedDB references
|
|
3
|
+
* Patches a MapboxStyle for offline use by replacing URLs with IndexedDB references.
|
|
4
|
+
*
|
|
5
|
+
* Safe to call repeatedly on the same stored style (every `addRegion` does):
|
|
6
|
+
* the first call stashes each source's upstream `tiles` / `maxzoom` under
|
|
7
|
+
* `__originalTiles` / `__originalMaxzoom`, and later calls patch from those,
|
|
8
|
+
* so the download pipeline can still reach the network and `maxzoom` can grow
|
|
9
|
+
* again when a deeper region is added.
|
|
10
|
+
*
|
|
4
11
|
* @param style - The style to patch
|
|
5
|
-
* @param downloadId -
|
|
6
|
-
* @param maxZoom -
|
|
12
|
+
* @param downloadId - Fallback ID for `idb://` URLs when `styleId` is omitted
|
|
13
|
+
* @param maxZoom - Max zoom downloaded for this style (the highest across its regions)
|
|
7
14
|
* @param tileExtension - Optional tile extension
|
|
8
|
-
* @param styleId -
|
|
9
|
-
*
|
|
10
|
-
*
|
|
15
|
+
* @param styleId - Style ID used in all `idb://` URLs. Tiles, glyphs, sprites and
|
|
16
|
+
* models are stored per style, so URLs keyed by style keep working
|
|
17
|
+
* when any one region is deleted.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Add a region's extra tile sources to a style, unless one with that id is
|
|
21
|
+
* already there. Sources must be in the style before it's patched for offline use.
|
|
22
|
+
*/
|
|
23
|
+
export declare function injectExtraSources(style: {
|
|
24
|
+
sources: Record<string, unknown>;
|
|
25
|
+
}, extraSources?: ReadonlyArray<{
|
|
26
|
+
id: string;
|
|
27
|
+
tiles: string[];
|
|
28
|
+
type?: string;
|
|
29
|
+
minzoom?: number;
|
|
30
|
+
maxzoom?: number;
|
|
31
|
+
attribution?: string;
|
|
32
|
+
}>): void;
|
|
33
|
+
/**
|
|
34
|
+
* Keep each model's upstream URL before the style is patched, the first time
|
|
35
|
+
* only. Patching points every model at `idb://`, so without this a model that
|
|
36
|
+
* failed to download couldn't be fetched again.
|
|
37
|
+
*/
|
|
38
|
+
export declare function stashOriginalModels(entry: {
|
|
39
|
+
style: object;
|
|
40
|
+
originalModels?: Record<string, unknown>;
|
|
41
|
+
}): void;
|
|
42
|
+
/**
|
|
43
|
+
* Point models that aren't stored back at their upstream URLs. Run after
|
|
44
|
+
* patching, which points every model at `idb://`.
|
|
11
45
|
*/
|
|
46
|
+
export declare function restoreUnstoredModels(entry: {
|
|
47
|
+
style: object;
|
|
48
|
+
originalModels?: Record<string, unknown>;
|
|
49
|
+
}, storedNames: ReadonlySet<string>): void;
|
|
50
|
+
/**
|
|
51
|
+
* Whether a style uses parts of the spec only Mapbox GL JS v3 draws: config
|
|
52
|
+
* (`schema`), 3D `models`, `lights` or `imports`. MapLibre rejects these.
|
|
53
|
+
*/
|
|
54
|
+
export declare function needsMapboxGl(style: object): boolean;
|
|
55
|
+
/** Whether a map instance is Mapbox GL JS v3, the only renderer with style config. */
|
|
56
|
+
export declare function isMapboxGlMap(map: unknown): boolean;
|
|
12
57
|
export declare function patchStyleForOffline(style: MapboxStyle, downloadId: string, maxZoom?: number, tileExtension?: string, styleId?: string): MapboxStyle;
|
|
58
|
+
type FontSchema = Record<string, {
|
|
59
|
+
default?: unknown;
|
|
60
|
+
}>;
|
|
13
61
|
/**
|
|
14
62
|
* Extract individual font names from a `text-font` layout property value.
|
|
15
63
|
*
|
|
16
|
-
* Handles
|
|
17
|
-
*
|
|
64
|
+
* Handles simple arrays (`["Font A", "Font B"]`), Mapbox GL expression syntax
|
|
65
|
+
* (e.g. `["step", ["zoom"], ["literal", ["Font A"]], 10, ["literal", ["Font B"]]]`),
|
|
66
|
+
* and Mapbox Standard's config-built stacks
|
|
67
|
+
* (`[["concat", ["config", "font"], " Medium"], "Arial Unicode MS Bold"]`).
|
|
18
68
|
*/
|
|
19
|
-
export declare function extractFontNamesFromTextField(textFont: unknown): string[];
|
|
69
|
+
export declare function extractFontNamesFromTextField(textFont: unknown, schema?: FontSchema): string[];
|
|
20
70
|
/**
|
|
21
71
|
* Normalize a style's `sprite` property into a uniform array of {id, url} sources.
|
|
22
72
|
* Handles string format, array format, and filters out already-patched idb:// URLs.
|
|
@@ -51,3 +101,4 @@ export declare function generateGlyphUrlsFromStyle(style: {
|
|
|
51
101
|
};
|
|
52
102
|
}>;
|
|
53
103
|
}, glyphsUrlTemplate: string, ranges?: Array<[number, number]>): string[];
|
|
104
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export interface TileRange {
|
|
2
|
+
minX: number;
|
|
3
|
+
maxX: number;
|
|
4
|
+
minY: number;
|
|
5
|
+
maxY: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* XYZ tile range covering `bounds` at zoom `z`. Shared by the download
|
|
9
|
+
* pipeline (which fetches exactly this range) and region-scoped consumers
|
|
10
|
+
* like MBTiles export, so both agree on which tiles belong to a region.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getTileRangeAtZoom(bounds: [[number, number], [number, number]], z: number): TileRange;
|
|
13
|
+
/**
|
|
14
|
+
* Whether tile `z/x/y` falls inside `bounds` and `[minZoom, maxZoom]`.
|
|
15
|
+
*/
|
|
16
|
+
export declare function isTileInRegion(z: number, x: number, y: number, region: {
|
|
17
|
+
bounds: [[number, number], [number, number]];
|
|
18
|
+
minZoom: number;
|
|
19
|
+
maxZoom: number;
|
|
20
|
+
}): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Zoom levels to download for one source in `region`: the overlap of the
|
|
23
|
+
* region's and the source's zoom ranges. When they don't overlap, the source
|
|
24
|
+
* still gets the zooms the map needs from it:
|
|
25
|
+
* - source ends below the region (`maxzoom` < region min) → its `maxzoom`,
|
|
26
|
+
* which the renderer overzooms for the region's zooms;
|
|
27
|
+
* - source starts above the region (`minzoom` > region max) → `minzoom`
|
|
28
|
+
* through `maxzoom` (or just `minzoom` if unbounded).
|
|
29
|
+
*/
|
|
30
|
+
export declare function sourceZoomRange(region: {
|
|
31
|
+
minZoom: number;
|
|
32
|
+
maxZoom: number;
|
|
33
|
+
}, sourceMinZoom?: number, sourceMaxZoom?: number): {
|
|
34
|
+
min: number;
|
|
35
|
+
max: number;
|
|
36
|
+
};
|
|
37
|
+
/** Zoom fields of a stored style source (possibly patched by patchStyleForOffline). */
|
|
38
|
+
export interface SourceZoomConfig {
|
|
39
|
+
minzoom?: number;
|
|
40
|
+
maxzoom?: number;
|
|
41
|
+
__originalMaxzoom?: number | null;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* A stored source's upstream `maxzoom`. Patched styles cap `maxzoom` for
|
|
45
|
+
* rendering and stash the upstream value under `__originalMaxzoom`.
|
|
46
|
+
*/
|
|
47
|
+
export declare function upstreamMaxzoom(source: SourceZoomConfig | undefined): number | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Whether a stored tile was downloaded for `region`: inside its bounds, at a
|
|
50
|
+
* zoom the download pipeline fetches for the tile's source (which can fall
|
|
51
|
+
* outside the region's own range — see `sourceZoomRange`). `sources` is the
|
|
52
|
+
* stored style's `sources`. Regions with malformed bounds match nothing.
|
|
53
|
+
*/
|
|
54
|
+
export declare function tileBelongsToRegion(tile: {
|
|
55
|
+
sourceId?: string;
|
|
56
|
+
z: number;
|
|
57
|
+
x: number;
|
|
58
|
+
y: number;
|
|
59
|
+
}, region: {
|
|
60
|
+
bounds: [[number, number], [number, number]];
|
|
61
|
+
minZoom: number;
|
|
62
|
+
maxZoom: number;
|
|
63
|
+
}, sources: Record<string, SourceZoomConfig | undefined>): boolean;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Validation utilities for common patterns
|
|
3
3
|
* Provides reusable validation functions to ensure data integrity
|
|
4
4
|
*/
|
|
5
|
-
import type { OfflineRegionOptions } from '../types';
|
|
5
|
+
import type { OfflineRegionOptions } from '../types/index.js';
|
|
6
6
|
/**
|
|
7
7
|
* Validate geographic bounds
|
|
8
8
|
* @param bounds - Array of two [lng, lat] coordinate pairs
|