Created
July 30, 2019 04:35
-
-
Save mpaccione/19b7f13ec8600bc37d2927b3ac696d84 to your computer and use it in GitHub Desktop.
CRON Server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Modules | |
const cors = require('cors'), | |
cron = require('node-cron'), | |
express = require('express'), | |
expressStaticGzip = require("express-static-gzip"), | |
path = require('path'), | |
request = require('request'), | |
THREE = require('three'), | |
app = express(), | |
// Globals | |
url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/", | |
urlSuffix = [ | |
"all_hour.geojson", | |
"all_day.geojson", | |
"all_week.geojson", | |
"all_month.geojson" | |
], | |
quakes = { | |
"0": [], | |
"1": [], | |
"2": [], | |
"3": [] | |
}, | |
threeData = { | |
"0": null, | |
"1": null, | |
"2": null, | |
"3": null | |
} | |
// CORS for Local Testing | |
app.use(cors()); | |
// Compression | |
app.use('/', expressStaticGzip(path.join(__dirname, 'build'), { | |
enableBrotli: true, | |
orderPreference: ['br', 'gz'] | |
})) | |
// Routes | |
app.get('/', function(req, res) { | |
res.sendFile(path.join(__dirname, 'build', 'index.html')) | |
}) | |
app.get('/.well-known(/*)?', function(req, res) { | |
res.sendFile(path.join(__dirname, '.well-known', 'assetlinks.json')) | |
}) | |
app.get('/privacy-policy', function(req, res) { | |
res.sendFile(path.join(__dirname, 'privacy_policy.html')) | |
}) | |
// API | |
app.get('/quakes/:index', function(req, res){ | |
res.setHeader('Content-Type', 'application/json'); | |
req.params.index != "all" ? res.json(quakes[req.params.index]) : res.json(quakes); | |
}); | |
app.get('/threeData/:index', function(req, res){ | |
res.setHeader('Content-Type', 'application/json'); | |
req.params.index != "all" ? res.json(threeData[req.params.index]) : res.json(threeData); | |
}); | |
app.get('/quakeData/:index', function(req, res){ | |
// Send Specific Selection or All | |
const jsonArr = req.params.index != "all" ? [ | |
quakes[req.params.index], | |
threeData[req.params.index] | |
] : [ | |
quakes, | |
threeData | |
] | |
res.setHeader('Content-Type', 'application/json'); | |
res.json(jsonArr); | |
}); | |
// Cron every minute | |
cron.schedule('*/1 * * * *', () => { | |
console.log("CRON JOB - "+new Date().getMinutes()); | |
// Loop over API urls, make AJAX reqs, store in global | |
for (let i = 0; i < urlSuffix.length; i++) { | |
request(url+urlSuffix[i], function (error, response, body) { | |
if (response.statusCode == 200) { | |
const parsedBody = JSON.parse(body), | |
quakeArr = new Array(parsedBody.metadata.count), | |
geom = new THREE.Geometry(), | |
cubeMat = new THREE.MeshBasicMaterial({ vertexColors: true }); | |
// Data Parsing | |
for (const feature of parsedBody.features) { | |
// Quake Obj | |
const magnitude = feature.properties.mag, | |
location = feature.properties.place, | |
time = feature.properties.time, | |
coordinates = feature.geometry.coordinates, | |
quake = { | |
"magnitude": magnitude, | |
"location": location, | |
"time": time, | |
"coordinates": coordinates | |
}, | |
// Three Data Obj | |
quakeVector = longLatToSphere(coordinates[0], coordinates[1], 600), | |
rgb = colorData(magnitude), | |
cubeColor = new THREE.Color(rgb), | |
cubeHeight = magnitude > 0 ? (magnitude ** 3) * 1.75 : 0, | |
cubeGeom = new THREE.BoxGeometry(3, 3, cubeHeight, 1, 1, 1), | |
cube = new THREE.Mesh(cubeGeom, cubeMat); | |
// set position of cube on globe, point to center, merge together for one draw call | |
for ( let j = 0; j < cubeGeom.faces.length; j ++ ) { | |
cubeGeom.faces[j].color = cubeColor; | |
} | |
cube.position.set(quakeVector.x, quakeVector.y, quakeVector.z); | |
cube.lookAt(new THREE.Vector3(0,0,0)); | |
cube.updateMatrix(); | |
geom.merge(cube.geometry, cube.matrix); | |
quakeArr.push(quake); | |
} | |
// Data Sorting by Highest Magnitude | |
quakeArr.sort((a, b) => b.magnitude - a.magnitude); | |
// Store in Global | |
quakes[i] = quakeArr; | |
threeData[i] = geom; | |
} else { | |
console.log(response); | |
console.log("error: "+response); | |
console.log(this); | |
} | |
}) | |
} | |
}) | |
// Three.js Viz Functions | |
// Intensity Coloring | |
colorData = percentage => { | |
let rgbString = "", | |
r = parseInt(percentage * 25.5), | |
g = 255 - r; | |
r = r < 0 ? 0 : r; | |
rgbString = `rgb(${r},${g}, 0)`; | |
return rgbString; | |
} | |
// Projection Mapping | |
longLatToSphere = (long, lat, radius) => { | |
const phi = (90-lat)*(Math.PI/180), | |
theta = (long+180)*(Math.PI/180), | |
x = -((radius) * Math.sin(phi)*Math.cos(theta)), | |
z = ((radius) * Math.sin(phi)*Math.sin(theta)), | |
y = ((radius) * Math.cos(phi)); | |
return new THREE.Vector3(x,y,z); | |
} | |
// Listen | |
app.listen(8080, () => console.log("Static client listening on 8080")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment