Skip to content

Commit

Permalink
Merge branch 'main' into feature/msavi-endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
wherop committed Dec 6, 2024
2 parents 526b1e9 + 8b13ba6 commit 78c31be
Show file tree
Hide file tree
Showing 15 changed files with 938 additions and 17 deletions.
9 changes: 8 additions & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ jobs:
working-directory: ./backend
env:
API_BASE_URL: "http://127.0.0.1:8000"
GOOGLE_EARTH_ENGINE_SERVICE_ACCOUNT_CREDENTIALS: ${{ secrets.GOOGLE_EARTH_ENGINE_SERVICE_ACCOUNT_CREDENTIALS }}
GOOGLE_EARTH_ENGINE_SERVICE_ACCOUNT_EMAIL: ${{ secrets.GOOGLE_EARTH_ENGINE_SERVICE_ACCOUNT_EMAIL }}
ENVIRONMENT: "PRODUCTION"
run: |
python -m pip install --upgrade pip
pip install -r requirements-dev.txt
Expand All @@ -81,7 +84,11 @@ jobs:
--allow-unauthenticated \
--platform=managed \
--min-instances=1 \
--max-instances=5
--max-instances=5 \
--set-env-vars "GOOGLE_EARTH_ENGINE_SERVICE_ACCOUNT_CREDENTIALS=${{ secrets.GOOGLE_EARTH_ENGINE_SERVICE_ACCOUNT_CREDENTIALS }}" \
--set-env-vars "GOOGLE_EARTH_ENGINE_SERVICE_ACCOUNT_EMAIL=${{ secrets.GOOGLE_EARTH_ENGINE_SERVICE_ACCOUNT_EMAIL }}" \
--set-env-vars "ENVIRONMENT=PRODUCTION"
# Step 9: Build and Deploy the frontend
- name: Build Docker image (frontend)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<template>
<v-container>
<h2 class="pb-10">Temperature vs. NDVI</h2>
<v-row justify="center">
<div
id="plotlyGraphTemperatureNdvi"
style="width: 100%; height: 400px"
class="d-flex justify-center"
></div>
</v-row>
</v-container>
</template>

<script>
import axios from 'axios'
import Plotly from 'plotly.js-dist-min'
import { onMounted, ref, render } from 'vue'
export default {
name: 'TemperatureNdviBarAndLine',
setup() {
const temperatureData = ref(null)
const ndviData = ref(null)
const startDate = ref(1514761200) // 2018-01-01
const endDate = ref(1733007599) // 2024-11-30
const temporalResolution = ref("Monthly") // options: "Daily", "Monthly"
const aggregation = ref("Mean") // options: "Mean", "Median", "Max", "Min"
const fetchTemperatureData = async () => {
const apiUrl = 'https://thf-climate-run-1020174331409.europe-west3.run.app/weather/index'
const params = {
weatherVariable: "temperature_2m",
startDate: startDate.value,
endDate: endDate.value,
location: "TEMPELHOFER_FELD",
temporalResolution: temporalResolution.value.toUpperCase(),
aggregation: aggregation.value.toUpperCase()
}
try {
const response = await axios.get(apiUrl, { params })
temperatureData.value = response.data
renderPlot()
} catch (error) {
console.error("Error fetching temperature data:", error)
}
}
const fetchNdviData = async () => {
const apiUrl = 'https://thf-climate-run-1020174331409.europe-west3.run.app/index/ndvi'
const params = {
startDate: startDate.value,
endDate: endDate.value,
location: "TEMPELHOFER_FELD",
temporalResolution: temporalResolution.value.toUpperCase(),
aggregation: aggregation.value.toUpperCase()
}
try {
const response = await axios.get(apiUrl, { params })
ndviData.value = response.data
renderPlot()
} catch (error) {
console.error("Error fetching NDVI data:", error)
}
}
const renderPlot = () => {
if (temperatureData.value && ndviData.value) {
const tempTimestamps = temperatureData.value.data.map(entry =>
new Date(entry.timestamp * 1000).toISOString().split('T')[0]
)
const tempValues = temperatureData.value.data.map(entry => entry.value)
const ndviTimestamps = ndviData.value.data.map(entry => new Date(entry.timestamp * 1000))
const ndviValues = ndviData.value.data.map(entry => entry.value)
const tempTrace = {
x: tempTimestamps,
y: tempValues,
type: 'bar', // can change to lines+markers
name: 'Temperature (°C)',
marker: { color: 'red' }
};
const ndviTrace = {
x: ndviTimestamps,
y: ndviValues,
mode: 'lines+markers',
name: 'NDVI',
line: { color: 'blue' },
yaxis: 'y2',
};
const layout = {
title: 'NDVI vs. Monthly Temperature for Tempelhofer Feld (2018-2024)',
xaxis: { title: 'Date', type: 'date', rangeslider: { visible: true } },
yaxis: { title: 'Temperature (°C)' },
yaxis2: {
title: 'NDVI',
overlaying: 'y',
side: 'right',
},
legend: { x: 1.1, y: 0.5 },
template: 'plotly_white'
};
Plotly.newPlot('plotlyGraphTemperatureNdvi', [tempTrace, ndviTrace], layout);
}
}
onMounted(() => {
fetchTemperatureData()
fetchNdviData()
})
}
}
</script>

<style scoped></style>
128 changes: 128 additions & 0 deletions frontend/src/components/CorrelationGraphs/TemperatureNdviScatter.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<template>
<v-container>
<v-row justify="center" class="pb-16">
<div
id="plotlyScatterTemperatureNdvi"
style="width: 100%; height: 400px"
class="d-flex justify-center"
></div>
</v-row>
</v-container>
</template>

<script>
import axios from 'axios'
import Plotly from 'plotly.js-dist-min'
import { onMounted, ref } from 'vue'
export default {
name: 'TemperatureNdviScatter',
setup() {
const temperatureData = ref(null)
const ndviData = ref(null)
const startDate = ref(1514761200) // 2018-01-01
const endDate = ref(1733007599) // 2024-11-30
const temporalResolution = ref("Monthly") // options: "Daily", "Monthly"
const aggregation = ref("Mean") // options: "Mean", "Median", "Max", "Min"
const fetchTemperatureData = async () => {
const apiUrl = 'https://thf-climate-run-1020174331409.europe-west3.run.app/weather/index'
const params = {
weatherVariable: "temperature_2m",
startDate: startDate.value,
endDate: endDate.value,
location: "TEMPELHOFER_FELD",
temporalResolution: temporalResolution.value.toUpperCase(),
aggregation: aggregation.value.toUpperCase()
}
try {
const response = await axios.get(apiUrl, { params })
temperatureData.value = response.data
renderPlot()
} catch (error) {
console.error("Error fetching temperature data:", error)
}
}
const fetchNdviData = async () => {
const apiUrl = 'https://thf-climate-run-1020174331409.europe-west3.run.app/index/ndvi'
const params = {
startDate: startDate.value,
endDate: endDate.value,
location: "TEMPELHOFER_FELD",
temporalResolution: temporalResolution.value.toUpperCase(),
aggregation: aggregation.value.toUpperCase()
}
try {
const response = await axios.get(apiUrl, { params })
ndviData.value = response.data
renderPlot()
} catch (error) {
console.error("Error fetching NDVI data:", error)
}
}
const renderPlot = () => {
if (temperatureData.value && ndviData.value) {
const tempValues = temperatureData.value.data.map(entry => entry.value)
const ndviValues = ndviData.value.data.map(entry => entry.value)
const timestamps = temperatureData.value.data.map(entry => entry.timestamp);
const monthsAndYears = timestamps.map(ts => {
const date = new Date(ts * 1000)
const month = date.toLocaleString('default', { month: 'long' })
const year = date.getFullYear()
return { month, year }
})
// Map months to a circular grayscale gradient
const months = monthsAndYears.map(({ month }) => new Date(Date.parse(month + " 1")).getMonth())
const monthColors = months.map(month => {
// Convert month index (0-11) to circular position
const angle = (month / 12) * 2 * Math.PI // 0-2π range
// Use cosine to create smooth gradient: July (π) = 0 (black), January (0) = 1 (white)
const intensity = Math.round((Math.cos(angle) + 1) / 2 * 255) // Scale cosine to 0-255
return `rgb(${intensity}, ${intensity}, ${intensity})`
})
const scatterTrace = {
x: tempValues,
y: ndviValues,
mode: 'markers',
marker: {
color: monthColors,
size: 8,
line: {
color: 'black',
width: 1,
},
},
type: 'scatter',
name: 'Temperature vs. NDVI',
hovertemplate: '%{x}°C<br>NDVI: %{y}<br>%{customdata.month} %{customdata.year}<extra></extra>',
customdata: monthsAndYears,
};
const layout = {
title: 'Scatter Plot of Temperature vs. NDVI',
xaxis: { title: 'Temperature (°C)' },
yaxis: { title: 'NDVI' },
template: 'plotly_white',
};
Plotly.newPlot('plotlyScatterTemperatureNdvi', [scatterTrace], layout)
}
}
onMounted(() => {
fetchTemperatureData()
fetchNdviData()
})
}
}
</script>

<style scoped></style>

23 changes: 19 additions & 4 deletions frontend/src/components/MainSection.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
<template>
<v-container class="main-section" fluid>
<Images />
<TemperatureNdviBarAndLine />
<TemperatureNdviScatter />
<TempDifferenceGraph />
<SoilTempDifferenceGraph />
<NdviDifferenceGraph />
<NdviOverlayGraph />
<!-- <Images />
<NdviComparisonGraph />
<NdviSelectMonthGraph />
<NdviOverlayGraph />
<MedianTempGraph />
<MeanSoilTempGraph />
<MeanSoilMoistureGraph />
<AugustMeanSoilTempGraph />
<SelectMonthMeanSoilTempGraph />
<SelectMonthMeanSoilTempGraph /> -->
</v-container>
</template>

Expand All @@ -22,6 +27,11 @@ import MeanSoilTempGraph from "./WeatherGraphs/SoilTempGraph.vue"
import MeanSoilMoistureGraph from "./WeatherGraphs/SoilMoistureGraph.vue"
import AugustMeanSoilTempGraph from "./WeatherGraphs/AugustSoilTempGraph.vue"
import SelectMonthMeanSoilTempGraph from "./WeatherGraphs/SelectMonthSoilTempGraph.vue"
import TemperatureNdviBarAndLine from "./CorrelationGraphs/TemperatureNdviBarAndLine.vue"
import TemperatureNdviScatter from "./CorrelationGraphs/TemperatureNdviScatter.vue"
import TempDifferenceGraph from "./WeatherGraphs/TempDifferenceGraph.vue"
import SoilTempDifferenceGraph from "./WeatherGraphs/SoilTempDifferenceGraph.vue"
import NdviDifferenceGraph from "./NdviGraphs/NdviDifferenceGraph.vue"
export default {
name: 'MainSection',
Expand All @@ -34,7 +44,12 @@ export default {
MeanSoilTempGraph,
MeanSoilMoistureGraph,
AugustMeanSoilTempGraph,
SelectMonthMeanSoilTempGraph
SelectMonthMeanSoilTempGraph,
TempDifferenceGraph,
SoilTempDifferenceGraph,
TemperatureNdviBarAndLine,
TemperatureNdviScatter,
NdviDifferenceGraph
}
}
</script>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/NdviGraphs/NdviComparisonGraph.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export default {
const aggregationOptions = ["Mean", "Median", "Max", "Min"]
const fetchNdviData = async (params) => {
const apiUrl = 'http://localhost:8000/index/ndvi'
const apiUrl = 'https://thf-climate-run-1020174331409.europe-west3.run.app/index/ndvi'
try {
const response = await axios.get(apiUrl, { params })
ndviData.value = response.data
Expand Down
Loading

0 comments on commit 78c31be

Please sign in to comment.