diff --git a/package-lock.json b/package-lock.json
index fc9ed4d..153df77 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,6 +13,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"
},
@@ -1078,6 +1079,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",
@@ -1109,6 +1115,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 5a20907..1730ef5 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,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/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 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {formatTime(currentHour)}
-
-
-
-
dispatchTimeUpdate()}
- class="timeline-slider"
- />
-
-
- {#each Array(Math.floor(totalHours / updateInterval) + 1) as _, i}
-
{
- currentHour = i * updateInterval;
- dispatchTimeUpdate();
- }}
- >
- {i * updateInterval % 24 === 0 ? `День ${Math.floor(i * updateInterval / 24) + 1}` : ''}
-
- {/each}
-
-
-
-
\ No newline at end of file
diff --git a/src/routes/WindVisualisation.svelte b/src/routes/WindVisualisation.svelte
index 713cde8..007b417 100644
--- a/src/routes/WindVisualisation.svelte
+++ b/src/routes/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(() => {