From 14ea970a68145bb2b8e5fbcfe232dbba473f678e Mon Sep 17 00:00:00 2001 From: Aryav Tiwari <58284558+aryavtiwari2005@users.noreply.github.com> Date: Sun, 6 Oct 2024 07:48:10 +0530 Subject: [PATCH 1/4] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index abc30b8b..47c5f110 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # NASA Space Apps Challenge 2024 [Noida] -#### Team Name - -#### Problem Statement - -#### Team Leader Email - +#### Team Name - CodeMonks +#### Problem Statement - Community Mapping +#### Team Leader Email - sahaj.23bcy10288@vitbhopal.ac.in ## A Brief of the Prototype: What is your solution? and how it works. From 07bede602a2ae57473a38586db8080706fc07c57 Mon Sep 17 00:00:00 2001 From: Aryav Tiwari <58284558+aryavtiwari2005@users.noreply.github.com> Date: Sun, 6 Oct 2024 07:56:43 +0530 Subject: [PATCH 2/4] Update README.md --- README.md | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 47c5f110..2945d0c6 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,31 @@ #### Team Leader Email - sahaj.23bcy10288@vitbhopal.ac.in ## A Brief of the Prototype: - What is your solution? and how it works. + The prototype you're building will be an interactive and innovative platform that connects space technology with societal benefits. Here’s a brief of its key components: -## Code Execution Instruction: - *[If your solution is **not** application based, you can ignore this para] + Space-Tech Impact Map: This core feature will display a dynamic map using NASA's satellite data, showcasing global space tech impacts like satellite installations, research centers, and observatories. It will highlight areas benefiting from space technology in sectors like disaster management, agriculture, and climate monitoring. + + Community-Driven Data Integration: Users from different communities will contribute local data, including feedback on space tech benefits or challenges. Contributions will be categorized for easy navigation, offering insights into how space tech affects specific regions. + + Geo-Spatial Analysis & Visualization: This will involve detailed analytics, displaying trends such as environmental shifts or improved infrastructure due to space tech. The map will feature heat maps, growth charts, and other visual insights to illustrate space tech’s impact on agriculture, communication, and education. + + Citizen Science Integration: This section will encourage users to conduct local research projects using NASA's data. Community members will be able to track environmental metrics like pollution or urban heat islands and collaborate with researchers globally. + + AR/VR Exploration Mode: For an immersive experience, users can explore the impact map in 3D using AR/VR technology. This feature will enable them to visualize space research impacts in their regions, enhancing engagement with the platform. - *The Repository must contain your **Execution Plan PDF**. + Sustainability & Policy Tracker: This feature will link space technology’s role with the UN’s Sustainable Development Goals (SDGs). It will track relevant policies and community recommendations on how space tech can support sustainable growth globally. + + The app's tech stack will involve front-end technologies like React.js, Three.js, D3.js for visualizations and AR/VR, Node.js and Express for backend services, and MongoDB for community data storage. For geo-spatial analysis, Google Earth Engine and Mapbox will be integrated. The app will be deployed on AWS or GCP for scalability and real-time access to NASA’s data. + + This prototype bridges space science with community development, making space tech more accessible to non-scientists while fostering collaboration between citizens, researchers, and NASA. + +## Code Execution Instruction: + Terminal 1: + cd frontend/ + npm i + npm start + + Terminal 2: + cd backend + npm i + node index.js From b8a7de04b8f0cbf02d8449c778611d1c4486ce6e Mon Sep 17 00:00:00 2001 From: Aryav Tiwari <58284558+aryavtiwari2005@users.noreply.github.com> Date: Sun, 6 Oct 2024 08:11:24 +0530 Subject: [PATCH 3/4] Add files via upload --- backend/index.js | 283 +++++++++++++++++++++++++++++++++++++++++++ backend/package.json | 19 +++ 2 files changed, 302 insertions(+) create mode 100644 backend/index.js create mode 100644 backend/package.json diff --git a/backend/index.js b/backend/index.js new file mode 100644 index 00000000..336c4816 --- /dev/null +++ b/backend/index.js @@ -0,0 +1,283 @@ +const express = require('express'); +const mongoose = require('mongoose'); +const app = express(); +const cors = require('cors') +const axios = require('axios'); +require('dotenv').config(); + +const PORT = process.env.PORT || 3000; +const NASA_API_BASE = 'https://api.nasa.gov/neo/rest/v1/neo/browse'; +const OPENWEATHER_API_KEY = process.env.OPENWEATHER_API_KEY; +const WEATHER_BASE_URL = 'https://api.openweathermap.org/data/2.5/weather'; + +const cache = { + data: new Map(), + timeout: 300000 +}; + +const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); + +app.use(express.json()); +app.use(express.urlencoded({ extended: true })); +app.use(cors()) +app.use((req, res, next) => { + res.header('Access-Control-Allow-Origin', '*'); + res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); + next(); +}); + +const fetchCoordinates = async (city) => { + const geocodeApiUrl = `https://api.opencagedata.com/geocode/v1/json`; + const response = await axios.get(geocodeApiUrl, { + params: { + q: city, + key: process.env.OPENCAGE_API_KEY + } + }); + + if (response.data && response.data.results.length > 0) { + const { lat, lng } = response.data.results[0].geometry; + return { lat, lon: lng }; + } else { + throw new Error('City not found'); + } + }; + +const fetchSatelliteData = async (lat, lon) => { + const nasaApiUrl = `https://api.nasa.gov/planetary/earth/assets`; + const response = await axios.get(nasaApiUrl, { + params: { + lon, + lat, + dim: 0.025, //11 kms + date: '2021-09-01', + api_key: process.env.NASA_API_KEY + } + }) + return response.data; +}; + +const fetchPollutionData = async (lat, lon) => { + const response = await axios.get('https://api.openaq.org/v2/latest', { + params: { + coordinates: `${lat},${lon}`, + radius: 2750, + limit: 1 + }, + headers: { + 'X-API-Key': process.env.OPENAQ_API_KEY + } + }); + return response.data; +}; + +async function fetchWeatherDataWithRetry(lat, lon, retries = 3) { + const cacheKey = `${lat}-${lon}`; + + if (cache.data.has(cacheKey) && + Date.now() - cache.data.get(cacheKey).timestamp < cache.timeout) { + return cache.data.get(cacheKey).data; + } + + try { + const response = await axios.get(WEATHER_BASE_URL, { + params: { + lat, + lon, + appid: OPENWEATHER_API_KEY, + units: 'metric' + } + }); + + const result = response.data; + cache.data.set(cacheKey, { + data: result, + timestamp: Date.now() + }); + + return result; + } catch (error) { + if (retries > 0 && error.response?.status === 429) { + await delay(1000); + return fetchWeatherDataWithRetry(lat, lon, retries - 1); + } + throw error; + } +} + +function generatePoints(bounds, count) { + const [minLng, minLat, maxLng, maxLat] = bounds; + const points = []; + + const aspectRatio = (maxLng - minLng) / (maxLat - minLat); + const rowCount = Math.floor(Math.sqrt(count / aspectRatio)); + const colCount = Math.floor(count / rowCount); + + const latStep = (maxLat - minLat) / rowCount; + const lngStep = (maxLng - minLng) / colCount; + + for (let lat = minLat; lat <= maxLat; lat += latStep) { + for (let lng = minLng; lng <= maxLng; lng += lngStep) { + points.push({ + latitude: parseFloat(lat.toFixed(6)), + longitude: parseFloat(lng.toFixed(6)) + }); + } + } + + return points; +} + +app.get('/api/satellite-data', async (req, res) => { + try { + const response = await axios.get(`${NASA_API_BASE}?api_key=${process.env.NASA_API_KEY}`); + const satelliteData = response.data.near_earth_objects; + + const mappedData = satelliteData.map((satellite) => ({ + name: satellite.name, + nasa_jpl_url: satellite.nasa_jpl_url, + is_potentially_hazardous: satellite.is_potentially_hazardous_asteroid, + close_approach_data: satellite.close_approach_data, + })); + + res.json(mappedData); + } catch (error) { + console.error('Error fetching satellite data:', error); + res.status(500).json({ error: 'Error fetching data from NASA API' }); + } +}); + +app.get('/api/heatmap', async (req, res) => { + try { + const { bounds, parameter = 'temperature' } = req.query; + + if (!bounds) { + return res.status(400).json({ + error: 'Missing required parameter: bounds' + }); + } + + const boundsArray = JSON.parse(bounds); + + const points = generatePoints(boundsArray, 50); + + const batchSize = 5; + const heatmapData = []; + + for (let i = 0; i < points.length; i += batchSize) { + const batch = points.slice(i, i + batchSize); + + const batchResults = await Promise.all( + batch.map(async (point, index) => { + try { + await delay(index * 200); + + const weatherData = await fetchWeatherDataWithRetry( + point.latitude, + point.longitude + ); + + let value; + switch (parameter) { + case 'temperature': + value = weatherData.main.temp; + break; + case 'humidity': + value = weatherData.main.humidity; + break; + case 'windSpeed': + value = weatherData.wind.speed; + break; + case 'cloudCover': + value = weatherData.clouds.all; + break; + case 'pressure': + value = weatherData.main.pressure; + break; + default: + value = weatherData.main.temp; + } + + return { + coordinates: [point.longitude, point.latitude], + value: value, + metadata: { + location: weatherData.name, + description: weatherData.weather[0].description + } + }; + } catch (error) { + console.error(`Error fetching data for point ${point.latitude},${point.longitude}:`, error); + return null; + } + }) + ); + + heatmapData.push(...batchResults.filter(result => result !== null)); + + await delay(1000); + } + + res.json({ + parameter, + points: heatmapData, + metadata: { + bounds: boundsArray, + pointCount: heatmapData.length, + timestamp: new Date().toISOString(), + parameterUnit: getParameterUnit(parameter) + } + }); + + } catch (error) { + console.error('Heatmap generation error:', error); + res.status(400).json({ + error: error.message || 'Error generating heatmap data' + }); + } +}); + +function getParameterUnit(parameter) { + switch (parameter) { + case 'temperature': + return '°C'; + case 'humidity': + return '%'; + case 'windSpeed': + return 'm/s'; + case 'cloudCover': + return '%'; + case 'pressure': + return 'hPa'; + default: + return ''; + } +} + +app.get('/api/city-data', async (req, res) => { + const { city } = req.query; + + try { + + const { lat, lon } = await fetchCoordinates(city).catch(err => { + throw new Error('Error fetching coordinates'); + }); + + const satelliteData = await fetchSatelliteData(lat, lon).catch(err => { + throw new Error('Error fetching satellite data'); + }); + + const pollutionData = await fetchPollutionData(lat, lon).catch(err => { + throw new Error('Error fetching pollution data'); + }); + + res.status(200).json({ satelliteData, pollutionData }); + + } catch (err) { + res.status(500).json({ error: err.message }); + } + }); + +app.listen(PORT, () => { + console.log('Server running on port 3000'); +}); \ No newline at end of file diff --git a/backend/package.json b/backend/package.json new file mode 100644 index 00000000..45318732 --- /dev/null +++ b/backend/package.json @@ -0,0 +1,19 @@ +{ + "name": "backend", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "description": "", + "dependencies": { + "axios": "^1.7.7", + "cors": "^2.8.5", + "dotenv": "^16.4.5", + "express": "^4.21.0", + "mongoose": "^8.7.0" + } +} From d2295f57c5626348516740a5ad72fe7a6ba6203d Mon Sep 17 00:00:00 2001 From: Aryav Tiwari Date: Sun, 6 Oct 2024 08:13:02 +0530 Subject: [PATCH 4/4] fixes --- .DS_Store | Bin 0 -> 6148 bytes frontend | 1 + 2 files changed, 1 insertion(+) create mode 100644 .DS_Store create mode 160000 frontend diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..27de4bb372651e57ed370cb0c39c96ae65cc8e87 GIT binary patch literal 6148 zcmeHK!A{#i5S>JO{*t>66yB;D^-AUReY7$WZWvqp0{vh1Xx+FF4Sph2h zjv*D4?&anz$(N$V@e&!}wQEp9F`dylJz77Lpoh1`4s_$r3M}3VKWRh;D_y$yWIDb~ zavOh>T;|!h+}gTTwUzptw~e3?tOnovzs$5>#^q$(jYlW^bZAVTEbKTr%7)WH^Zhqd zlyO!JM>Zi#hX^@6&WhAbyJk|PW1HJ|9YGj`gXY?7)@gri>Gr4Xc}vf}eD1V#XS+S0 zhrx&S&94W8^ZcSPzwO9LVV7EY=Wzj7FhV+@UCg#e`@jvlSnT8nCaw|nn2ANUpfDf| z2m`N;0e>0>tFLX~GG1Xo82IN5@cE#jjFHF6p*=d#*b)F(huaEl{%PbK?J@FLIYbXc zxm2J_RldYfE**aD<06lhLzhm<7az)hS@{Y@*{|dM+J=*g97-z;2m?