| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- const OFFLINE_MAP_DIR_KEY = 'OFFLINE_MAP_DIR__';
- const OFFLINE_MAP_SERVER_DIR_KEY = 'OFFLINE_MAP_SERVER_DIR__';
- export const OFFLINE_MAP_DIR_CHANGED_EVENT = 'offline-map-dir-changed';
- const LOCAL_MAP_PROTOCOL = 'localmap://';
- function isValidOfflineMapPath(value: string) {
- const text = String(value || '').trim();
- if (!text) return false;
- if (text === '[object Object]') return false;
- if (text === 'null' || text === 'undefined') return false;
- return (
- /^[a-zA-Z]:[\\/]/.test(text) ||
- text.startsWith('/') ||
- text.startsWith('file://') ||
- text.startsWith(LOCAL_MAP_PROTOCOL)
- );
- }
- function normalizePath(value: string) {
- const text = String(value || '').trim();
- if (!isValidOfflineMapPath(text)) return '';
- return text.replace(/[\\/]+$/, '');
- }
- export function getOfflineMapDir() {
- try {
- const serverDir = normalizePath(window.localStorage.getItem(OFFLINE_MAP_SERVER_DIR_KEY) || '');
- if (serverDir) return serverDir;
- return normalizePath(window.localStorage.getItem(OFFLINE_MAP_DIR_KEY) || '');
- } catch {
- return '';
- }
- }
- export function getManualOfflineMapDir() {
- try {
- return normalizePath(window.localStorage.getItem(OFFLINE_MAP_DIR_KEY) || '');
- } catch {
- return '';
- }
- }
- export function getServerOfflineMapDir() {
- try {
- return normalizePath(window.localStorage.getItem(OFFLINE_MAP_SERVER_DIR_KEY) || '');
- } catch {
- return '';
- }
- }
- export function setOfflineMapDir(path: string) {
- const normalized = normalizePath(path);
- try {
- if (!normalized) {
- window.localStorage.removeItem(OFFLINE_MAP_DIR_KEY);
- window.dispatchEvent(new CustomEvent(OFFLINE_MAP_DIR_CHANGED_EVENT, { detail: '' }));
- return;
- }
- window.localStorage.setItem(OFFLINE_MAP_DIR_KEY, normalized);
- window.dispatchEvent(new CustomEvent(OFFLINE_MAP_DIR_CHANGED_EVENT, { detail: normalized }));
- } catch {}
- }
- export function clearOfflineMapDir() {
- setOfflineMapDir('');
- }
- export function setServerOfflineMapDir(path: string) {
- const normalized = normalizePath(path);
- try {
- if (!normalized) {
- window.localStorage.removeItem(OFFLINE_MAP_SERVER_DIR_KEY);
- window.dispatchEvent(new CustomEvent(OFFLINE_MAP_DIR_CHANGED_EVENT, { detail: getOfflineMapDir() }));
- return;
- }
- window.localStorage.setItem(OFFLINE_MAP_SERVER_DIR_KEY, normalized);
- window.dispatchEvent(new CustomEvent(OFFLINE_MAP_DIR_CHANGED_EVENT, { detail: normalized }));
- } catch {}
- }
- export function buildFileUrl(filePath: string) {
- const normalized = normalizePath(filePath).replace(/\\/g, '/');
- if (!normalized) return '';
- if (new RegExp(`^${LOCAL_MAP_PROTOCOL}`, 'i').test(normalized)) return normalized;
- if (/^file:\/\//i.test(normalized)) return toLocalMapUrl(normalized);
- if (/^[a-zA-Z]:/.test(normalized)) {
- return encodeURI(`${LOCAL_MAP_PROTOCOL}/${normalized}`);
- }
- return encodeURI(`${LOCAL_MAP_PROTOCOL}${normalized.startsWith('/') ? '' : '/'}${normalized}`);
- }
- export function getOfflineMapPmtilesUrl(fileName = 'china.pmtiles') {
- const dir = getOfflineMapDir();
- if (!dir) return '';
- return buildFileUrl(`${dir}/${fileName}`);
- }
- export function getOfflineMapFileUrl(fileName: string) {
- const dir = getOfflineMapDir();
- if (!dir || !fileName) return '';
- return buildFileUrl(`${dir}/${fileName}`);
- }
- export function getOfflineMapFilePath(fileName: string) {
- const dir = getOfflineMapDir();
- if (!dir || !fileName) return '';
- return normalizePath(`${dir}/${fileName}`);
- }
- export function toLocalMapUrl(value: string) {
- const text = String(value || '').trim();
- if (!text) return '';
- if (new RegExp(`^${LOCAL_MAP_PROTOCOL}`, 'i').test(text)) return text;
- if (/^file:\/\//i.test(text)) {
- try {
- const url = new URL(text);
- const pathname = decodeURIComponent(url.pathname || '');
- const normalized = /^[\\/][a-zA-Z]:/.test(pathname) ? pathname.slice(1) : pathname;
- return buildFileUrl(normalized);
- } catch {
- return text;
- }
- }
- if (/^[a-zA-Z]:/.test(text) || text.startsWith('/')) {
- return buildFileUrl(text);
- }
- return text;
- }
- export class ElectronPmtilesSource {
- filePath: string;
- constructor(filePath: string) {
- this.filePath = normalizePath(filePath);
- }
- getKey() {
- return this.filePath;
- }
- async getBytes(offset: number, length: number) {
- const ipcRenderer = (window as any)?.electron?.ipcRenderer;
- if (!ipcRenderer?.invoke || !this.filePath || !length) {
- return { data: new ArrayBuffer(0) };
- }
- const payload =
- (await ipcRenderer.invoke('controller/os/readBinaryFileRange', {
- filePath: this.filePath,
- offset,
- length,
- })) || {};
- const base64 = String(payload?.data || '');
- const size = Number(payload?.size || 0);
- if (!base64 || !size) {
- return { data: new ArrayBuffer(0) };
- }
- const binary = window.atob(base64);
- const bytes = new Uint8Array(binary.length);
- for (let index = 0; index < binary.length; index += 1) {
- bytes[index] = binary.charCodeAt(index);
- }
- return { data: bytes.buffer };
- }
- }
|