From 31f5d84b706eaa03b1f90ea20633b45cfc89cf27 Mon Sep 17 00:00:00 2001 From: Jeff Bliss Date: Thu, 29 Aug 2024 15:58:30 -0400 Subject: [PATCH] basic functionality of slider and ndvi working --- .prettierrc => .prettierrc.json | 1 + src/App.jsx | 210 ++++++++++++++++++++++---------- src/components/NDVIButton.jsx | 11 +- src/components/NDVIChart.jsx | 89 ++++++++++---- src/config.js | 125 +++++++++---------- src/utils.js | 60 +++++---- 6 files changed, 324 insertions(+), 172 deletions(-) rename .prettierrc => .prettierrc.json (88%) diff --git a/.prettierrc b/.prettierrc.json similarity index 88% rename from .prettierrc rename to .prettierrc.json index e27083cf..93b49966 100644 --- a/.prettierrc +++ b/.prettierrc.json @@ -10,4 +10,5 @@ "jsxSingleQuote": false, "bracketSameLine": false, "endOfLine": "lf", + "singleAttributePerLine": true } \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx index 3ccd596c..d77cf249 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import dayjs from 'dayjs'; import { Marker, MapContainer, Popup, useMap, useMapEvents, WMSTileLayer } from 'react-leaflet'; import { Box, Paper, Slider } from '@mui/material'; @@ -10,6 +10,7 @@ import Grid from '@mui/material/Unstable_Grid2'; // Grid version 2 import CloseIcon from '@mui/icons-material/Close'; import PlayArrowIcon from '@mui/icons-material/PlayArrow'; import PauseIcon from '@mui/icons-material/Pause'; +import ShowChartIcon from '@mui/icons-material/ShowChart'; import styled from '@emotion/styled'; import { useQuery } from '@tanstack/react-query'; import XMLParser from 'react-xml-parser'; @@ -20,10 +21,8 @@ import BasicSelect from './components/BasicSelect'; import BasicButton from './components/BasicButton'; import BasicText from './components/BasicText.jsx'; import NDVIChart from './components/NDVIChart.jsx'; -import BasicDatePicker from './components/BasicDatePicker'; -import DateSlider from './components/DateSlider'; import { config } from './config'; -import { webMercatorToLatLng, convertStringToDate, parseDateString } from './utils.js'; +import { webMercatorToLatLng, convertStringToDate, parseDateString, convertDateToString } from './utils.js'; import NDVIButtonWrapper from './components/NDVIButton.jsx'; export const StyledMapContainer = styled(MapContainer)(() => ({ @@ -32,21 +31,22 @@ export const StyledMapContainer = styled(MapContainer)(() => ({ })); function App() { - const [map, setMap] = React.useState(null); - const [ndviData, setNdviData] = React.useState([]); - const [showGraph, setShowGraph] = React.useState(false); - const [popupPosition, setPopupPosition] = React.useState(null); - const [changeProduct, setChangeProduct] = React.useState(config.wmsLayers['FW3 1 year']); - const [mask, setMask] = React.useState(config.masks['MaskForForest']); - const [overlay, setOverlay] = React.useState(config.vectorLayers['Tropical Cyclone Lines Since 1980']); - const [basemap, setBasemap] = React.useState(config.basemaps['ArcGIS Imagery']); - const [availableLayers, setAvailableLayers] = React.useState([]); - const [activeLayerIndex, setActiveLayerIndex] = React.useState(0); - const [startDate, setStartDate] = React.useState(dayjs('2024-07-01')); - const [endDate, setEndDate] = React.useState(dayjs('2024-07-08')); - const [isPlaying, setIsPlaying] = React.useState(false); - const [playSpeed, setPlaySpeed] = React.useState(config.playSpeeds['2x']); - const [unFilteredLayers, setUnfilteredLayers] = React.useState([]); + const [map, setMap] = useState(null); + const [ndviData, setNdviData] = useState([]); + const [ndviDataSubset, setNdviDataSubset] = useState([]); + const [showGraph, setShowGraph] = useState(false); + const [popupPosition, setPopupPosition] = useState(null); + const [changeProduct, setChangeProduct] = useState(config.wmsLayers['Net Ecological 3 Year']); + const [mask, setMask] = useState(config.masks['MaskForForest']); + const [overlay, setOverlay] = useState(config.vectorLayers['Tropical Cyclone Lines Since 1980']); + const [basemap, setBasemap] = useState(config.basemaps['ArcGIS Imagery']); + const [availableLayers, setAvailableLayers] = useState([]); + const [activeLayerIndex, setActiveLayerIndex] = useState(0); + const [startDate, setStartDate] = useState(dayjs('2017-01-01')); + const [endDate, setEndDate] = useState(dayjs('2018-01-01')); + const [isPlaying, setIsPlaying] = useState(false); + const [playSpeed, setPlaySpeed] = useState(config.playSpeeds['2x']); + const [unFilteredLayers, setUnfilteredLayers] = useState([]); const intervalRef = React.useRef(null); const onSelectedDateChange = (event) => { @@ -66,6 +66,14 @@ function App() { } }); setAvailableLayers(allLayers); + + // filter ndvi values + setNdviDataSubset( + ndviData.filter((item) => { + const date = convertStringToDate(item.name); + return date >= newStartDate && date <= endDate; + }) + ); }; const endDateChanged = (event) => { @@ -80,6 +88,14 @@ function App() { } }); setAvailableLayers(allLayers); + + // filter ndvi values + setNdviDataSubset( + ndviData.filter((item) => { + const date = convertStringToDate(item.name); + return date >= startDate && date <= newEndDate; + }) + ); }; const handleChangeProductChange = (event) => { @@ -165,11 +181,15 @@ function App() { enabled: !!changeProduct?.url, }); - if (isPending) console.log('isPending'); - if (error) return 'An error has occurred: ' + error.message; + if (isPending) { + console.log('isPending'); + } + if (error) { + console.log('An error has occurred: ' + error.message); + } // Update available layers when the getCapabilities query has returned - React.useEffect(() => { + useEffect(() => { if (!data) return; const layers = data?.getElementsByTagName('Layer'); const queryableLayers = layers.filter((layer) => layer.attributes.queryable === '1'); @@ -208,8 +228,16 @@ function App() { const centerLng = (southWest[1] + northWest[1] + northEast[1] + southEast[1]) / 4; return ( - - + + - + - + - + - + - startDateChanged(event)} /> + startDateChanged(event)} + /> - + - + - endDateChanged(event)} /> + endDateChanged(event)} + /> - + : } label={isPlaying ? 'Pause' : 'Animate'} onClick={(event) => handleIsPlayingPress(event)} /> - + - - + + {/*{availableLayers.map((layer, index) => (*/} {/* */} {/*))}*/} - - + {/**/} + {/**/} {/*
*/} {/*
*/} {/* */} {/*
*/} {/*
*/} -
+
-
+
- + {showGraph && } {showGraph && ( - - - - + + {/**/} + {/**/} + + { const { handler } = props; @@ -39,7 +39,7 @@ const createNdviButtonControl = (props) => { const NDVIButton = createControlComponent(createNdviButtonControl); export default function NDVIButtonWrapper(props) { - const { popupPosition, setPopupPosition, setShowGraph, setNdviData } = props; + const { popupPosition, startDate, endDate, setPopupPosition, setShowGraph, setNdviData, setNdviDataSubset } = props; // TODO: Change this to actual ForWarn data and not LanDAT const ndviEndpoint = 'https://4desh2uig8.execute-api.us-east-1.amazonaws.com/prod/landat-ndvi'; const map = useMap(); @@ -67,7 +67,12 @@ export default function NDVIButtonWrapper(props) { }; }); setNdviData(ndviData); - console.log(ndviData); + setNdviDataSubset( + ndviData.filter(item => { + const date = convertStringToDate(item.name); + return (date >= startDate && date <= endDate); + }) + ) }, [data]); const ndviClickHandler = (e) => { diff --git a/src/components/NDVIChart.jsx b/src/components/NDVIChart.jsx index e7a59904..5bfdd419 100644 --- a/src/components/NDVIChart.jsx +++ b/src/components/NDVIChart.jsx @@ -1,26 +1,73 @@ -import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend } from 'recharts'; - -// Dummy data for the chart -const data = [ - { name: '20000108', pv: 2400, amt: 2400 }, - { name: '20000116', pv: 1398, amt: 2210 }, - { name: '20000124', pv: 9800, amt: 2290 }, - { name: '20000201', pv: 3908, amt: 2000 }, - { name: '20000209', pv: 4800, amt: 2181 }, - { name: '20000217', pv: 3800, amt: 2500 }, - { name: '20000225', pv: 4300, amt: 2100 }, -]; +import { useState, useEffect } from 'react'; +import { ResponsiveContainer, LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend } from 'recharts'; + const NDVIChart = (props) => { - const { ndviData } = props; + const { data, activeLayerIndex } = props; + const [dotsData, setDotsData] = useState([{ x: 0, y: 0 }]); + const [activeDotPosition, setActiveDotPosition] = useState({ x: 0, y: 0 }); + + // if (activeDotPosition != dotsData[activeLayerIndex]) { + // setActiveDotPosition(dotsData[activeLayerIndex]); + // } + + useEffect(() => { + setActiveDotPosition(dotsData[activeLayerIndex]); + }, [activeLayerIndex]); + + const getDotsData = () => { + const dotsList = []; + const dots = document.querySelectorAll('.recharts-dot'); + if (dots.length) { + Array.from(dots).map((item) => { + dotsList.push({ x: item.getAttribute('cx'), y: item.getAttribute('cy') }); + }); + setDotsData(dotsList); + console.log('animation End'); + } + }; + + const CustomTooltip = ({ active, payload, label }) => { + if (active && payload && payload.length) { + console.log(payload); + return ( +
+

{`${data[activeLayerIndex].name} : ${data[activeLayerIndex].ndvi}`}

+
+ ); + } + + return null; + }; + return ( - - - - - - - - + + + + + + } + cursor={false} + isAnimationActive={true} + active={true} + position={{ x: 0 - -1 * activeDotPosition.x, y: -50 - -1 * activeDotPosition.y }} + /> + + { + getDotsData(); + }} + type="monotone" + dataKey="ndvi" + stroke="#8884d8" + dot={true} + activeDot={{ r: 8, fill: '#8884d8', stroke: '#fff' }} + /> + + ); }; diff --git a/src/config.js b/src/config.js index 940c00ab..a5d2ae59 100644 --- a/src/config.js +++ b/src/config.js @@ -4,10 +4,11 @@ export const config = { wmsUrl: wmsUrl, wmsUrlFull: wmsUrlFull, agolApiKey: 'AAPK961d021a9f344f7c95eaadbeb6c6f39ajXC7QTZMufrPPCzqo0NN_ta6FKKzOb8GDutDr1ipDWZMVMPT-Mgy4CNcnKIXJTdu', - mapCenter: [26.9517, -82.4588], + mapCenter: [36.9517, -82.4588], mapZoom: 7, projectName: 'New FCAV', - playSpeeds: { // in milliseconds + playSpeeds: { + // in milliseconds '1x': 2000, '2x': 1000, '4x': 500, @@ -16,192 +17,192 @@ export const config = { 'FW3 1 year': { name: 'FW3 1 year', url: wmsUrl.concat('forwarn3_products_1yr.map'), - layer_regex: /^forwarn3_products_1yr_(\d{4})(\d{2})(\d{2})$/ + layer_regex: /^forwarn3_products_1yr_(\d{4})(\d{2})(\d{2})$/, }, - 'forwarn3_products_1yr': { + forwarn3_products_1yr: { name: 'forwarn3_products_1yr', url: wmsUrl.concat('test_runtime_sub.map'), - layer_regex: /^forwarn3_products_1yr_(\d{4})(\d{2})(\d{2})$/ + layer_regex: /^forwarn3_products_1yr_(\d{4})(\d{2})(\d{2})$/, }, 'FW3 2 year Early Detect': { name: 'FW3 2 year Early Detect', url: wmsUrl, - layer_regex: /^forwarn3_products_2yrED_(\d{4})(\d{2})(\d{2})$/ + layer_regex: /^forwarn3_products_2yrED_(\d{4})(\d{2})(\d{2})$/, }, 'FW3 2 year Early Early Detect': { name: 'FW3 2 year Early Early Detect', url: wmsUrl, - layer_regex: /^forwarn3_products_2yrEED_(\d{4})(\d{2})(\d{2})$/ + layer_regex: /^forwarn3_products_2yrEED_(\d{4})(\d{2})(\d{2})$/, }, 'FW3 3 year': { name: 'FW3 3 year', url: wmsUrl, - layer_regex: /^forwarn3_products_3yr_(\d{4})(\d{2})(\d{2})$/ + layer_regex: /^forwarn3_products_3yr_(\d{4})(\d{2})(\d{2})$/, }, 'FW3 5 year': { name: 'FW3 5 year', url: wmsUrl, - layer_regex: /^forwarn3_products_5yr_(\d{4})(\d{2})(\d{2})$/ + layer_regex: /^forwarn3_products_5yr_(\d{4})(\d{2})(\d{2})$/, }, 'FW3 Adapative Baseline All Years': { name: 'FW3 Adapative Baseline All Years', url: wmsUrl, - layer_regex: /^forwarn3_products_adaptivebaseline_allyr_(\d{4})(\d{2})(\d{2})$/ + layer_regex: /^forwarn3_products_adaptivebaseline_allyr_(\d{4})(\d{2})(\d{2})$/, }, 'FW3 Adaptive Baseline Days Diff': { name: 'FW3 Adapative Baseline Days Diff', url: wmsUrl, - layer_regex: /^forwarn3_products_adaptivebaseline_daysdiff_(\d{4})(\d{2})(\d{2})$/ + layer_regex: /^forwarn3_products_adaptivebaseline_daysdiff_(\d{4})(\d{2})(\d{2})$/, }, 'FW3 Early Detect': { name: 'FW3 Early Detect', url: wmsUrl, - layer_regex: /^forwarn3_products_ED_(\d{4})(\d{2})(\d{2})$/ + layer_regex: /^forwarn3_products_ED_(\d{4})(\d{2})(\d{2})$/, }, 'FW3 Early Early Detect': { name: 'FW3 Early Early Detect', url: wmsUrl, - layer_regex: /^forwarn3_products_EED_(\d{4})(\d{2})(\d{2})$/ + layer_regex: /^forwarn3_products_EED_(\d{4})(\d{2})(\d{2})$/, }, 'FW3 Phenoregions Early Detect': { name: 'FW3 Phenoregions Early Detect', url: wmsUrl, - layer_regex: /^forwarn3_products_phenoregionED_(\d{4})(\d{2})(\d{2})$/ + layer_regex: /^forwarn3_products_phenoregionED_(\d{4})(\d{2})(\d{2})$/, }, 'FW3 Phenoregions Early Early Detect': { name: 'FW3 Phenoregions Early Early Detect', url: wmsUrl, - layer_regex: /^forwarn3_products_phenoregionEED_(\d{4})(\d{2})(\d{2})$/ + layer_regex: /^forwarn3_products_phenoregionEED_(\d{4})(\d{2})(\d{2})$/, }, 'FW3 Phenoregions Baseline': { name: 'FW3 Phenoregions Baseline', url: wmsUrl, - layer_regex: /^forwarn3_products_phenoregions_baseline_(\d{4})(\d{2})(\d{2})$/ + layer_regex: /^forwarn3_products_phenoregions_baseline_(\d{4})(\d{2})(\d{2})$/, }, 'FW3 Phenoregions Regional Only': { name: 'FW3 Phenoregions Regional Only', url: wmsUrl, - layer_regex: /^forwarn3_products_phenoregions_regionalonly_(\d{4})(\d{2})(\d{2})$/ + layer_regex: /^forwarn3_products_phenoregions_regionalonly_(\d{4})(\d{2})(\d{2})$/, }, 'FW3 Phenoregions Seasonal Progress': { name: 'FW3 Phenoregions Seasonal Progress', url: wmsUrl, - layer_regex: /^forwarn3_products_phenoregions_seasonalprogress_(\d{4})(\d{2})(\d{2})$/ + layer_regex: /^forwarn3_products_phenoregions_seasonalprogress_(\d{4})(\d{2})(\d{2})$/, }, 'Net Ecological 0 Year': { name: 'Net Ecological 0 Year', - url: wmsUrl, - layer_regex: /^net_ecological_impact_dev_products_0yr_dev_(\d{4})(\d{2})(\d{2})$/ + url: wmsUrl.concat('net_ecological_impact_dev_products_0yr_dev.map'), + layer_regex: /^net_ecological_impact_dev_products_0yr_dev_(\d{4})(\d{2})(\d{2})$/, }, 'Net Ecological 1 Year': { name: 'Net Ecological 1 Year', - url: wmsUrl, - layer_regex: /^net_ecological_impact_dev_products_1yr_dev_(\d{4})(\d{2})(\d{2})$/ + url: wmsUrl.concat('net_ecological_impact_dev_products_1yr_dev.map'), + layer_regex: /^net_ecological_impact_dev_products_1yr_dev_(\d{4})(\d{2})(\d{2})$/, }, 'Net Ecological 2 Year': { name: 'Net Ecological 2 Year', - url: wmsUrl, - layer_regex: /^net_ecological_impact_dev_products_2yr_dev_(\d{4})(\d{2})(\d{2})$/ + url: wmsUrl.concat('net_ecological_impact_dev_products_2yr_dev.map'), + layer_regex: /^net_ecological_impact_dev_products_2yr_dev_(\d{4})(\d{2})(\d{2})$/, }, 'Net Ecological 3 Year': { name: 'Net Ecological 3 Year', - url: wmsUrl, - layer_regex: /^net_ecological_impact_dev_products_3yr_dev_(\d{4})(\d{2})(\d{2})$/ + url: wmsUrl.concat('net_ecological_impact_dev_products_3yr_dev.map'), + layer_regex: /^net_ecological_impact_dev_products_3yr_dev_(\d{4})(\d{2})(\d{2})$/, }, 'Net Ecological 4 Year': { name: 'Net Ecological 4 Year', - url: wmsUrl, - layer_regex: /^net_ecological_impact_dev_products_4yr_dev_(\d{4})(\d{2})(\d{2})$/ + url: wmsUrl.concat('net_ecological_impact_dev_products_4yr_dev.map'), + layer_regex: /^net_ecological_impact_dev_products_4yr_dev_(\d{4})(\d{2})(\d{2})$/, }, 'Net Ecological 5 Year': { name: 'Net Ecological 5 Year', - url: wmsUrl, - layer_regex: /^net_ecological_impact_dev_products_5yr_dev_(\d{4})(\d{2})(\d{2})$/ + url: wmsUrl.concat('net_ecological_impact_dev_products_5yr_dev.map'), + layer_regex: /^net_ecological_impact_dev_products_5yr_dev_(\d{4})(\d{2})(\d{2})$/, }, }, vectorLayers: { 'Current Large Incidents': { name: 'Current Large Incidents', url: wmsUrl.concat('fire.map'), - layerName: 'Current-Large-incidents' + layerName: 'Current-Large-incidents', }, 'Tropical Cyclone Lines 2022': { name: 'Tropical Cyclone Lines 2022', url: wmsUrl.concat('vlayers.map'), - layerName: 'tropical_cyclone_lines_2022' + layerName: 'tropical_cyclone_lines_2022', }, 'Tropical Cyclone Lines 2023': { name: 'Tropical Cyclone Lines 2023', url: wmsUrl.concat('vlayers.map'), - layerName: 'tropical_cyclone_lines_2023' + layerName: 'tropical_cyclone_lines_2023', }, 'Tropical Cyclone Lines Since 1980': { name: 'Tropical Cyclone Lines Since 1980', url: wmsUrl.concat('vector_map_files/tropical_cyclone_lines.map'), - layerName: 'tropical_cyclone_lines_since_1980' - } + layerName: 'tropical_cyclone_lines_since_1980', + }, }, masks: { - 'NoMask': { + NoMask: { name: 'NoMask', description: 'No Mask', }, - 'MaskForForest': { + MaskForForest: { name: 'MaskForForest', description: 'Mask for Forest', }, - 'MaskForAgriculture': { + MaskForAgriculture: { name: 'MaskForAgriculture', - description: 'Mask for Agriculture' + description: 'Mask for Agriculture', }, - 'MaskForConiferForest': { + MaskForConiferForest: { name: 'MaskForConiferForest', - description: 'Mask for Conifer Forest' + description: 'Mask for Conifer Forest', }, - 'MaskForDeciduousForest': { + MaskForDeciduousForest: { name: 'MaskForDeciduousForest', - description: 'Mask for Deciduous Forest' + description: 'Mask for Deciduous Forest', }, - 'MaskForGrass': { + MaskForGrass: { name: 'MaskForGrass', - description: 'Mask for Grass' + description: 'Mask for Grass', }, - 'MaskForMixedForest': { + MaskForMixedForest: { name: 'MaskForMixedForest', - description: 'Mask for Mixed Forest' + description: 'Mask for Mixed Forest', }, - 'MaskForNonVegetated': { + MaskForNonVegetated: { name: 'MaskForNonVegetated', - description: 'Mask for Non-Vegetated' + description: 'Mask for Non-Vegetated', }, - 'MaskForShrubland': { + MaskForShrubland: { name: 'MaskForShrubland', - description: 'Mask for Shrubland' + description: 'Mask for Shrubland', }, - 'MaskForUrban': { + MaskForUrban: { name: 'MaskForUrban', - description: 'Mask for Urban' + description: 'Mask for Urban', }, - 'MaskForWetland': { + MaskForWetland: { name: 'MaskForWetland', - description: 'Mask for Wetland' - } + description: 'Mask for Wetland', + }, }, basemaps: { 'ArcGIS Dark Gray': { name: 'ArcGIS Dark Gray', description: 'ArcGIS Dark Gray', - basemap: 'arcgis/dark-gray' + basemap: 'arcgis/dark-gray', }, 'ArcGIS Light Gray': { name: 'ArcGIS Light Gray', description: 'ArcGIS Light Gray', - basemap: 'arcgis/light-gray' + basemap: 'arcgis/light-gray', }, 'ArcGIS Imagery': { name: 'ArcGIS Imagery', description: 'ArcGIS Imagery', - basemap: 'arcgis/imagery' - } - } -} + basemap: 'arcgis/imagery', + }, + }, +}; diff --git a/src/utils.js b/src/utils.js index 4ca0c731..7adf3f96 100644 --- a/src/utils.js +++ b/src/utils.js @@ -2,44 +2,54 @@ import L from 'leaflet'; // Function to convert Web Mercator (EPSG:3857) to WGS84 (EPSG:4326) export function webMercatorToLatLng(x, y) { - const lng = (x / 20037508.34) * 180; - let lat = (y / 20037508.34) * 180; - lat = 180 / Math.PI * (2 * Math.atan(Math.exp(lat * Math.PI / 180)) - Math.PI / 2); - return [lat, lng]; + const lng = (x / 20037508.34) * 180; + let lat = (y / 20037508.34) * 180; + lat = (180 / Math.PI) * (2 * Math.atan(Math.exp((lat * Math.PI) / 180)) - Math.PI / 2); + return [lat, lng]; } // Function to calculate center and zoom from extent export function calculateCenterAndZoom(extent) { - const [minX, minY, maxX, maxY] = extent.split(',').map(Number); + const [minX, minY, maxX, maxY] = extent.split(',').map(Number); - const southWest = webMercatorToLatLng(minX, minY); - const northEast = webMercatorToLatLng(maxX, maxY); + const southWest = webMercatorToLatLng(minX, minY); + const northEast = webMercatorToLatLng(maxX, maxY); - const bounds = L.latLngBounds(southWest, northEast); - const center = bounds.getCenter(); + const bounds = L.latLngBounds(southWest, northEast); + const center = bounds.getCenter(); - // Create a map instance to use Leaflet's zoom calculation - const map = L.map(document.createElement('div')); - const zoom = map.getBoundsZoom(bounds); + // Create a map instance to use Leaflet's zoom calculation + const map = L.map(document.createElement('div')); + const zoom = map.getBoundsZoom(bounds); - return { center: [center.lat, center.lng], zoom }; + return { center: [center.lat, center.lng], zoom }; } export function convertStringToDate(dateString) { - const year = dateString.slice(0, 4); - const month = dateString.slice(4, 6); - const day = dateString.slice(6, 8); - return new Date(`${year}-${month}-${day}T00:00:00-04:00`); -}; + const year = dateString.slice(0, 4); + const month = dateString.slice(4, 6); + const day = dateString.slice(6, 8); + return new Date(`${year}-${month}-${day}T00:00:00-04:00`); +} + +// converts date to string like "20240828" +export function convertDateToString(date) { + console.log('jeff', date); + const year = date.getFullYear(); + const month = (date.getMonth() + 1).toString().padStart(2, '0'); + const day = date.getDate().toString().padStart(2, '0'); + + return `${year}${month}${day}`; +} // parses "2024-06-26_2024-07-19.napolygon.1yrdeparture.LAEA.img" into "20240719 export function parseDateString(inputString) { - // Split the string by underscore and period - const parts = inputString.split('_')[1].split('.'); + // Split the string by underscore and period + const parts = inputString.split('_')[1].split('.'); - // Extract the date part (2024-07-19) - const datePart = parts[0]; + // Extract the date part (2024-07-19) + const datePart = parts[0]; - // Remove hyphens and return only the digits - return datePart.replace(/-/g, ''); -} \ No newline at end of file + // Remove hyphens and return only the digits + return datePart.replace(/-/g, ''); +}