mirror of
https://github.com/asimonson1125/asimonson1125.github.io.git
synced 2026-02-25 05:09:49 -06:00
Update hotspots for legend
This commit is contained in:
@@ -8,8 +8,8 @@ body {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
#map {
|
||||
height: 100vh;
|
||||
html, body, #map {
|
||||
height: 100%;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
@@ -23,3 +23,17 @@ body {
|
||||
.leaflet-tile-pane {
|
||||
filter: brightness(50%);
|
||||
}
|
||||
|
||||
.legend {
|
||||
border: solid #999999 3px;
|
||||
color: #eee;
|
||||
background-color: rgba(44, 44, 44, .8);
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
#legendOccGrad {
|
||||
background-image: linear-gradient(to right, transparent, red);
|
||||
padding: 0 2em;
|
||||
text-align: center;
|
||||
text-shadow: black .2em .2em;
|
||||
}
|
||||
@@ -58,12 +58,12 @@ let map = L.map("map", {
|
||||
// let green = parseInt("78", 16);
|
||||
// let style = {"fillColor": `#${red.toString(16)}${green.toString(16)}00`};
|
||||
let ratio = attrs.properties.count / attrs.properties.capacity;
|
||||
ratio = ratio > 1 ? 1 : ratio;
|
||||
let red = 255 * ratio;
|
||||
let style = { fillColor: `rgba(${red}, 0, 0, ${ratio})` };
|
||||
let adjustedratio = ratio > 1 ? 1 : ratio;
|
||||
let red = 255 * adjustedratio;
|
||||
let style = { fillColor: `rgba(255, 0, 0, ${adjustedratio})` };
|
||||
ref.setStyle(style);
|
||||
ref.bindPopup(
|
||||
`${attrs.properties.name}<br />Current Occupation: ${attrs.properties.count}`
|
||||
`${attrs.properties.name}<br />Current Occupation: ${attrs.properties.count}<br />${Math.round(ratio*100)}% capacity`
|
||||
);
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ let map = L.map("map", {
|
||||
};
|
||||
|
||||
const geojsonMarkerOptions = {
|
||||
pane: "nodePane",
|
||||
radius: 8,
|
||||
fillColor: "#ff7800",
|
||||
color: "#ff7800",
|
||||
@@ -139,8 +140,12 @@ let map = L.map("map", {
|
||||
}
|
||||
|
||||
let pts;
|
||||
const densityMapUrl = "/hotspotsrit" // https://maps.rit.edu/proxySearch/densityMapDetail.php?mdo=1
|
||||
async function init() {
|
||||
let nodePane = map.createPane("nodePane");
|
||||
nodePane.style.zIndex = "600";
|
||||
let nodeGroup;
|
||||
const densityMapUrl = "/hotspotsrit"; // https://maps.rit.edu/proxySearch/densityMapDetail.php?mdo=1
|
||||
|
||||
async function init(legend = false) {
|
||||
let counts = fetch(densityMapUrl + "/cached");
|
||||
|
||||
let locations = fetch(
|
||||
@@ -156,7 +161,8 @@ let map = L.map("map", {
|
||||
for (let i = 0; i < counts.length; i++) {
|
||||
if (counts[i].mdo_id == x.properties.mdo_id) {
|
||||
x.properties.count = counts[i].count;
|
||||
x.properties.capacity = counts[i].max_occ == null ? 100 : counts[i].max_occ;
|
||||
x.properties.capacity =
|
||||
counts[i].max_occ == null ? 100 : counts[i].max_occ;
|
||||
x = ritCustomizeCoords(x);
|
||||
pts[x.properties.mdo_id] = x;
|
||||
break;
|
||||
@@ -175,7 +181,8 @@ let map = L.map("map", {
|
||||
}
|
||||
});
|
||||
|
||||
let ptsLayer = L.geoJSON(Object.values(pts), {
|
||||
nodeGroup = L.geoJSON(Object.values(pts), {
|
||||
pane: "nodePane",
|
||||
pointToLayer: function (feature, latlng) {
|
||||
return L.circleMarker(latlng, geojsonMarkerOptions);
|
||||
},
|
||||
@@ -188,17 +195,65 @@ let map = L.map("map", {
|
||||
}
|
||||
},
|
||||
onEachFeature: onEachFeature,
|
||||
}).addTo(map);
|
||||
});
|
||||
nodeGroup.addTo(map);
|
||||
nodeGroup.bringToFront();
|
||||
|
||||
const features = ptsLayer.getLayers();
|
||||
const features = nodeGroup.getLayers();
|
||||
for (let i = 0; i < features.length; i++) {
|
||||
const key = features[i].feature.properties.mdo_id;
|
||||
pts[key].properties.reference = features[i];
|
||||
}
|
||||
|
||||
legend ? makeLegend() : null;
|
||||
}
|
||||
|
||||
// let laid = L.geoJson(pts).addTo(map)
|
||||
// laid.remove()
|
||||
function makeLegend() {
|
||||
let legend = L.control({ position: "bottomright" });
|
||||
|
||||
legend.onAdd = function (mapref) {
|
||||
let div = L.DomUtil.create("div", "info legend");
|
||||
div.innerHTML = "<div id='legendOccGrad'>Occupancy / Max Occupancy Gradient</div>"
|
||||
div.innerHTML +=
|
||||
`<p>Markers represent locations where data is collected<br />
|
||||
Vectors represent the migration of aggregate occupation</br>
|
||||
vectors to/from nodeless points involve locations not tracked by RIT</p>`;
|
||||
|
||||
return div;
|
||||
};
|
||||
|
||||
let statControl = L.control({ position: "topright" });
|
||||
|
||||
statControl.onAdd = function (mapref) {
|
||||
let div = L.DomUtil.create("div", "info legend");
|
||||
div.innerHTML = "<p>Occupancy is updated every 5 minutes<br /><br /><span id='shotCounter'></span><br />Next update in <span id='countdownClock'></span> seconds</p>"
|
||||
return div;
|
||||
//
|
||||
};
|
||||
|
||||
statControl.addTo(map);
|
||||
legend.addTo(map);
|
||||
}
|
||||
|
||||
function updateLegend(shotcount=undefined){
|
||||
document.getElementById('shotCounter').textContent = `Previous update created ${shotcount} migration${shotcount == 1 ? "" : "s"}`;
|
||||
}
|
||||
|
||||
const space_coords = [43.09224, -77.674799];
|
||||
const UC_coords = [43.080361, -77.683296];
|
||||
const perkins_coords = [43.08616, -77.661796];
|
||||
function setSpace(features) {
|
||||
features.forEach((x) => {
|
||||
const centroid = getCoordArray(x);
|
||||
if (centroid[1] > -77.673157) {
|
||||
x.properties.space = perkins_coords;
|
||||
} else if (centroid[1] < -77.677503 && centroid[0] < 43.08395) {
|
||||
x.properties.space = UC_coords;
|
||||
} else {
|
||||
x.properties.space = space_coords;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let bullets = L.layerGroup([]);
|
||||
async function shootVector(
|
||||
@@ -288,9 +343,16 @@ let map = L.map("map", {
|
||||
});
|
||||
}
|
||||
|
||||
const space = [43.09224, -77.674799];
|
||||
let countdownTo;
|
||||
function updateCountdown() {
|
||||
const now = new Date().getTime();
|
||||
document.getElementById('countdownClock').textContent = Math.round((countdownTo - now) / 1000);
|
||||
}
|
||||
|
||||
async function getUpdate() {
|
||||
console.log("Updating Occupancy Matrix");
|
||||
countdownTo = new Date().getTime() + 5 * 60 * 1000;
|
||||
|
||||
let counts = await fetch(densityMapUrl + "/current");
|
||||
counts = await counts.json();
|
||||
|
||||
@@ -324,6 +386,7 @@ let map = L.map("map", {
|
||||
timeBetween / 1000
|
||||
} second intervals`
|
||||
);
|
||||
updateLegend(shots.length);
|
||||
for (let i = 0; i < shots.length; i++) {
|
||||
loadShot(shots[i], timeDelay[i], { trail: true });
|
||||
}
|
||||
@@ -405,12 +468,12 @@ let map = L.map("map", {
|
||||
// if no more people on campus, get them from space
|
||||
sourcesAndSinks.forEach((x) => {
|
||||
while (x.properties.diff > 0) {
|
||||
shots.push([x, space]);
|
||||
shots.push([x, x.properties.space]);
|
||||
x.properties.diff--;
|
||||
}
|
||||
|
||||
while (x.properties.diff < 0) {
|
||||
shots.push([space, x]);
|
||||
shots.push([x.properties.space, x]);
|
||||
x.properties.diff++;
|
||||
}
|
||||
});
|
||||
@@ -418,13 +481,16 @@ let map = L.map("map", {
|
||||
return shots;
|
||||
}
|
||||
|
||||
init().then(() => {
|
||||
const useLegend = window.location.pathname.replaceAll("/", "") == "hotspots"
|
||||
init(useLegend).then(() => {
|
||||
// map.on("click", () => {
|
||||
// shootVector(pts[2], pts[8]);
|
||||
// });
|
||||
// shootVector(pts[0], pts[1], {speed: 500});
|
||||
calcDistances(Object.values(pts));
|
||||
getUpdate()
|
||||
let ptsarr = Object.values(pts);
|
||||
calcDistances(ptsarr);
|
||||
setSpace(ptsarr);
|
||||
getUpdate();
|
||||
setInterval(updateCountdown, 1000);
|
||||
setInterval(getUpdate, 60000 * 5);
|
||||
});
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
{
|
||||
"Lower 48 Alt. Energy Map": {
|
||||
"RIT Hotspots": {
|
||||
"status": "WIP",
|
||||
"classes": "pinned geospacial programming",
|
||||
"bgi": "hotspotsrit.png",
|
||||
"content": "Live crowd migration map using RIT occupancy data",
|
||||
"links": [
|
||||
[
|
||||
"github", "https://github.com/asimonson1125/hotspotsrit", "git repo"
|
||||
],
|
||||
[
|
||||
"globe", "https://asimonson.com/hotspots", "demo"
|
||||
]
|
||||
]
|
||||
},
|
||||
"LogicFlow": {
|
||||
"status": "incomplete",
|
||||
"classes": "programming",
|
||||
"bgi": "logicflow.jpg",
|
||||
"content": "Translate paragraphs to logical flowcharts, powered by ChatGPT Winner of CSHacks' Best Use of AI by Paychex",
|
||||
"links": [
|
||||
[
|
||||
"github", "https://github.com/asimonson1125/LogicFlow", "git repo"
|
||||
],
|
||||
[
|
||||
"globe", "https://devpost.com/software/logicflow", "Hackathon listing"
|
||||
]
|
||||
]
|
||||
},
|
||||
"Alternative Energy Map": {
|
||||
"status": "complete",
|
||||
"classes": "pinned geospacial",
|
||||
"bgi": "geovisF.png",
|
||||
@@ -14,7 +42,7 @@
|
||||
},
|
||||
"OccupyRIT": {
|
||||
"status": "WIP",
|
||||
"classes": "pinned programming",
|
||||
"classes": "programming",
|
||||
"bgi": "occupyRIT.png",
|
||||
"content": "Collects RIT Gym Occupancy data, determining busiest workout times",
|
||||
"links": [
|
||||
|
||||
BIN
src/static/photos/hotspotsrit.png
Normal file
BIN
src/static/photos/hotspotsrit.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 350 KiB |
BIN
src/static/photos/logicflow.jpg
Normal file
BIN
src/static/photos/logicflow.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
Reference in New Issue
Block a user