diff --git a/package-lock.json b/package-lock.json index 6bb8971..1c6cabe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "js-cookie": "^3.0.5", "leaflet": "^1.9.4", "leaflet-heatmap": "^1.0.0", + "leaflet-timedimension": "^1.1.1", "leaflet-velocity": "^2.1.4", "leaflet.heat": "^0.2.0" }, @@ -1102,6 +1103,11 @@ "@types/estree": "^1.0.6" } }, + "node_modules/iso8601-js-period": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/iso8601-js-period/-/iso8601-js-period-0.2.1.tgz", + "integrity": "sha512-iDyz2TQFBd5WhCZjruOwHj01JkQGu7YbVLCVdpA7lCGEcBzE3ffCPAhLh/M8TAp//kCixPpYN4XU54WHCxvD2Q==" + }, "node_modules/js-cookie": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", @@ -1133,6 +1139,15 @@ "leaflet": "*" } }, + "node_modules/leaflet-timedimension": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/leaflet-timedimension/-/leaflet-timedimension-1.1.1.tgz", + "integrity": "sha512-ejXldN94veRsWka1vpC+4rbH+2+3d3ztn2xYx4jcXtjYDrKC/sNnoqCmyH2UEYIy51PI2851aI2k8uGdOEbhlw==", + "dependencies": { + "iso8601-js-period": "^0.2.1", + "leaflet": "~0.7.4 || ~1" + } + }, "node_modules/leaflet-velocity": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/leaflet-velocity/-/leaflet-velocity-2.1.4.tgz", diff --git a/package.json b/package.json index cb7085e..9bae6d0 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "js-cookie": "^3.0.5", "leaflet": "^1.9.4", "leaflet-heatmap": "^1.0.0", + "leaflet-timedimension": "^1.1.1", "leaflet-velocity": "^2.1.4", "leaflet.heat": "^0.2.0" } diff --git a/src/lib/components/WindVisualisation.svelte b/src/lib/components/WindVisualisation.svelte index 3cd67bb..4950b6a 100644 --- a/src/lib/components/WindVisualisation.svelte +++ b/src/lib/components/WindVisualisation.svelte @@ -5,10 +5,13 @@ import 'leaflet-velocity/dist/leaflet-velocity.css'; import 'leaflet-velocity/dist/leaflet-velocity'; import 'leaflet.heat'; + import 'leaflet-timedimension'; export let map; // принимаем карту из родительского компонента export let windData; + let timeDimension; + let timeDimensionControl; let velocityLayer; let heatLayer; let legend; @@ -18,6 +21,22 @@ let showVectors = true; let layerControl; + // Преобразование testVelo.json в формат timeData + const prepareTimeData = (windData) => { + if (!windData || windData.length < 2) return {}; + + // Используем дату из header или текущую дату, если не указана + const refTime = windData[0]?.header?.refTime || new Date().toISOString(); + + return { + [refTime]: { + u: windData[0].data, // U-компонента (первый объект в массиве) + v: windData[1].data // V-компонента (второй объект) + } + }; + }; + + // Функция для нормализации данных тепловой карты const prepareHeatData = (windData) => { if (!windData || windData.length < 2) { @@ -55,9 +74,9 @@ // Вычисляем координаты для текущей точки const y = Math.floor(i / nx); const x = i % nx; - const lat = la1 - y * dy; - const lng = lo1 + x * dx; - + let lat = la1 - y * dy; + let lng = lo1 + x * dx; + if (lng >= 180) lng -= 360; heatData.push([lat, lng, speed]); maxSpeed = Math.max(maxSpeed, speed); } @@ -82,9 +101,9 @@ try { return L.heatLayer(data, { - radius: 20, // Увеличьте радиус для глобальной карты - blur: 15, - maxZoom: 10, + radius: 8, // Увеличьте радиус для глобальной карты + blur: 20, + // maxZoom: 10, minOpacity: 0.7, gradient: { 0.1: 'blue', @@ -189,7 +208,50 @@ }; onMount(() => { - updateLayers(); + if (!map) return; + + // 1. Настройка TimeDimension (добавьте эти строки в начале) + // L.TimeDimension.Util.setProxy('https://your-proxy.com/?url='); // Для загрузки больших данных + L.TimeDimension.Util.setCacheLimit(10); // Лимит кэшированных кадров + + // 1. Подготовка данных + const timeData = prepareTimeData(windData); + const firstTime = Object.keys(timeData)[0]; + + // Инициализация TimeDimension + timeDimension = new L.TimeDimension({ + period: "PT1H", // Интервал 1 час + timeInterval: '${firstTime}/${firstTime}', + }); + + // Добавляем контролы времени + timeDimensionControl = new L.Control.TimeDimension({ + timeDimension, + position: 'bottomleft', + // autoPlay: true, + playerOptions: { + // transitionTime: 1000, + loop: false, + minBufferReady: -1 + } + }); + map.addControl(timeDimensionControl); + + // 4. Создание слоев + const velocityLayer = L.timeDimension.layer.windVelocity({ + displayValues: true, + data: timeData, + displayOptions: { + velocityType: 'Wind Speed', + position: 'bottomleft' + } + }).addTo(map); + + // 5. Тепловая карта (адаптируйте под ваш формат) + const heatLayer = L.timeDimension.layer.heat({ + radius: 15, + data: prepareTimeHeatData(timeData) + }).addTo(map); }); onDestroy(() => { diff --git a/src/routes/TimeLine.svelte b/src/routes/TimeLine.svelte index 94dddeb..e69de29 100644 --- a/src/routes/TimeLine.svelte +++ b/src/routes/TimeLine.svelte @@ -1,215 +0,0 @@ - - - -