Skip to content

Commit fe8d72a

Browse files
committedMar 21, 2021
Deploy Level 1
1 parent e2d23c8 commit fe8d72a

File tree

12 files changed

+778
-7
lines changed

12 files changed

+778
-7
lines changed
 

‎Images/level1.JPG

114 KB
Loading
File renamed without changes.

‎Level1/index.html

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
8+
<title>Leaflet Step-1</title>
9+
<!-- bootstrap -->
10+
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
11+
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
12+
<!-- Leaflet CSS -->
13+
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css"
14+
integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
15+
crossorigin="" />
16+
17+
<!-- Our CSS -->
18+
<link rel="stylesheet" type="text/css" href="../static/css/style.css">
19+
</head>
20+
21+
<body>
22+
<!-- <div class= 'container'> -->
23+
<!-- <div class= 'row'> -->
24+
<h1 class = "title"> Earthquakes with magnitud
25+
more than 2.5 Ritcher Scale in the last month
26+
<a href="../index.html" class="btn btn-primary">Home</a>
27+
</h1>
28+
</div>
29+
30+
<!-- The div that holds our map -->
31+
<!-- <section> -->
32+
<div id="map" class = row></div>
33+
<!-- </section> -->
34+
<!-- </div> -->
35+
<!-- Leaflet JS -->
36+
<script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"
37+
integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew=="
38+
crossorigin=""></script>
39+
<!-- D3 JavaScript -->
40+
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.3/d3.min.js"></script>
41+
<script src="https://d3js.org/d3.v6.min.js"></script>
42+
<!-- API key -->
43+
<script type="text/javascript" src="static/js/config.js"></script>
44+
<!-- Our JavaScript -->
45+
<!-- <script type="text/javascript" src="static/js/logic.js"></script> -->
46+
<script type="text/javascript" src="static/js/level1.js"></script>
47+
48+
<!-- Leaflet heatmap plugin-->
49+
<script type="text/javascript" src="static/js/leaflet-heat.js"></script>
50+
</body>
51+
52+
</html>

‎Level1/static/js/config.js

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// API key
2+
const API_KEY = "sk.eyJ1IjoibHVpc2YtcnVpeiIsImEiOiJja2traDU0ZXoyOHI1MnBxdWo3dmloOTlwIn0.NlVbgLCzZN13fgmbLeni-Q";

‎Level1/static/js/leaflet-heat.js

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
(c) 2014, Vladimir Agafonkin
3+
simpleheat, a tiny JavaScript library for drawing heatmaps with Canvas
4+
https://github.com/mourner/simpleheat
5+
*/
6+
!(function() {
7+
8+
9+
function t(i) {
10+
return this instanceof t ? (this._canvas = i = typeof i === "string" ? document.getElementById(i) : i, this._ctx = i.getContext("2d"), this._width = i.width, this._height = i.height, this._max = 1, void this.clear()) : new t(i);
11+
}t.prototype = { defaultRadius: 25,
12+
defaultGradient: { 0.4: "blue", 0.6: "cyan", 0.7: "lime", 0.8: "yellow", 1: "red" },
13+
data: function(t, i) {
14+
return this._data = t, this;
15+
},
16+
max: function(t) {
17+
return this._max = t, this;
18+
},
19+
add: function(t) {
20+
return this._data.push(t), this;
21+
},
22+
clear: function() {
23+
return this._data = [], this;
24+
},
25+
radius: function(t, i) {
26+
i = i || 15; var a = this._circle = document.createElement("canvas"),
27+
s = a.getContext("2d"),
28+
e = this._r = t + i; return a.width = a.height = 2 * e, s.shadowOffsetX = s.shadowOffsetY = 200, s.shadowBlur = i, s.shadowColor = "black", s.beginPath(), s.arc(e - 200, e - 200, t, 0, 2 * Math.PI, !0), s.closePath(), s.fill(), this;
29+
},
30+
gradient: function(t) {
31+
var i = document.createElement("canvas"),
32+
a = i.getContext("2d"),
33+
s = a.createLinearGradient(0, 0, 0, 256); i.width = 1, i.height = 256; for (var e in t)s.addColorStop(e, t[e]); return a.fillStyle = s, a.fillRect(0, 0, 1, 256), this._grad = a.getImageData(0, 0, 1, 256).data, this;
34+
},
35+
draw: function(t) {
36+
this._circle || this.radius(this.defaultRadius), this._grad || this.gradient(this.defaultGradient); var i = this._ctx; i.clearRect(0, 0, this._width, this._height); for (var a, s = 0, e = this._data.length; e > s; s++)a = this._data[s], i.globalAlpha = Math.max(a[2] / this._max, t || 0.05), i.drawImage(this._circle, a[0] - this._r, a[1] - this._r); var n = i.getImageData(0, 0, this._width, this._height); return this._colorize(n.data, this._grad), i.putImageData(n, 0, 0), this;
37+
},
38+
_colorize: function(t, i) {
39+
for (var a, s = 3, e = t.length; e > s; s += 4)a = 4 * t[s], a && (t[s - 3] = i[a], t[s - 2] = i[a + 1], t[s - 1] = i[a + 2]);
40+
} }, window.simpleheat = t;
41+
}()), /*
42+
(c) 2014, Vladimir Agafonkin
43+
Leaflet.heat, a tiny and fast heatmap plugin for Leaflet.
44+
https://github.com/Leaflet/Leaflet.heat
45+
*/
46+
L.HeatLayer = (L.Layer ? L.Layer : L.Class).extend({ initialize: function(t, i) {
47+
this._latlngs = t, L.setOptions(this, i);
48+
},
49+
setLatLngs: function(t) {
50+
return this._latlngs = t, this.redraw();
51+
},
52+
addLatLng: function(t) {
53+
return this._latlngs.push(t), this.redraw();
54+
},
55+
setOptions: function(t) {
56+
return L.setOptions(this, t), this._heat && this._updateOptions(), this.redraw();
57+
},
58+
redraw: function() {
59+
return !this._heat || this._frame || this._map._animating || (this._frame = L.Util.requestAnimFrame(this._redraw, this)), this;
60+
},
61+
onAdd: function(t) {
62+
this._map = t, this._canvas || this._initCanvas(), t._panes.overlayPane.appendChild(this._canvas), t.on("moveend", this._reset, this), t.options.zoomAnimation && L.Browser.any3d && t.on("zoomanim", this._animateZoom, this), this._reset();
63+
},
64+
onRemove: function(t) {
65+
t.getPanes().overlayPane.removeChild(this._canvas), t.off("moveend", this._reset, this), t.options.zoomAnimation && t.off("zoomanim", this._animateZoom, this);
66+
},
67+
addTo: function(t) {
68+
return t.addLayer(this), this;
69+
},
70+
_initCanvas: function() {
71+
var t = this._canvas = L.DomUtil.create("canvas", "leaflet-heatmap-layer leaflet-layer"),
72+
i = L.DomUtil.testProp(["transformOrigin", "WebkitTransformOrigin", "msTransformOrigin"]); t.style[i] = "50% 50%"; var a = this._map.getSize(); t.width = a.x, t.height = a.y; var s = this._map.options.zoomAnimation && L.Browser.any3d; L.DomUtil.addClass(t, "leaflet-zoom-" + (s ? "animated" : "hide")), this._heat = simpleheat(t), this._updateOptions();
73+
},
74+
_updateOptions: function() {
75+
this._heat.radius(this.options.radius || this._heat.defaultRadius, this.options.blur), this.options.gradient && this._heat.gradient(this.options.gradient), this.options.max && this._heat.max(this.options.max);
76+
},
77+
_reset: function() {
78+
var t = this._map.containerPointToLayerPoint([0, 0]); L.DomUtil.setPosition(this._canvas, t); var i = this._map.getSize(); this._heat._width !== i.x && (this._canvas.width = this._heat._width = i.x), this._heat._height !== i.y && (this._canvas.height = this._heat._height = i.y), this._redraw();
79+
},
80+
_redraw: function() {
81+
var t,
82+
i,
83+
a,
84+
s,
85+
e,
86+
n,
87+
h,
88+
o,
89+
r,
90+
d = [],
91+
_ = this._heat._r,
92+
l = this._map.getSize(),
93+
m = new L.Bounds(L.point([-_, -_]), l.add([_, _])),
94+
c = void 0 === this.options.max ? 1 : this.options.max,
95+
u = void 0 === this.options.maxZoom ? this._map.getMaxZoom() : this.options.maxZoom,
96+
f = 1 / Math.pow(2, Math.max(0, Math.min(u - this._map.getZoom(), 12))),
97+
g = _ / 2,
98+
p = [],
99+
v = this._map._getMapPanePos(),
100+
w = v.x % g,
101+
y = v.y % g; for (t = 0, i = this._latlngs.length; i > t; t++) {
102+
if (a = this._map.latLngToContainerPoint(this._latlngs[t]), m.contains(a)) {
103+
e = Math.floor((a.x - w) / g) + 2, n = Math.floor((a.y - y) / g) + 2; var x = void 0 !== this._latlngs[t].alt ? this._latlngs[t].alt : void 0 !== this._latlngs[t][2] ? +this._latlngs[t][2] : 1; r = x * f, p[n] = p[n] || [], s = p[n][e], s ? (s[0] = (s[0] * s[2] + a.x * r) / (s[2] + r), s[1] = (s[1] * s[2] + a.y * r) / (s[2] + r), s[2] += r) : p[n][e] = [a.x, a.y, r];
104+
}
105+
} for (t = 0, i = p.length; i > t; t++) if (p[t]) for (h = 0, o = p[t].length; o > h; h++)s = p[t][h], s && d.push([Math.round(s[0]), Math.round(s[1]), Math.min(s[2], c)]); this._heat.data(d).draw(this.options.minOpacity), this._frame = null;
106+
},
107+
_animateZoom: function(t) {
108+
var i = this._map.getZoomScale(t.zoom),
109+
a = this._map._getCenterOffset(t.center)._multiplyBy(-i).subtract(this._map._getMapPanePos()); L.DomUtil.setTransform ? L.DomUtil.setTransform(this._canvas, a, i) : this._canvas.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString(a) + " scale(" + i + ")";
110+
} }), L.heatLayer = function(t, i) {
111+
return new L.HeatLayer(t, i);
112+
};

‎Level1/static/js/level1.js

+167
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
// Store our API endpoint inside queryUrl
2+
let earthquakesUrl = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_month.geojson"
3+
// https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2014-01-01&endtime=+2014-01-02&maxlongitude=-69.52148437&minlongitude=-123.83789062&maxlatitude=48.74894534&minlatitude=25.16517337
4+
5+
// Perform a GET request to the query URL
6+
d3.json(earthquakesUrl).then(data => {
7+
// define earthquake Data
8+
let earthquakeData = data.features;
9+
// Once we get a response, send the data.features object to the createFeatures function
10+
createFeatures(earthquakeData);
11+
});
12+
13+
// Define a function we want to run once for each feature in the features array
14+
function createFeatures(earthquakeData) {
15+
16+
// Create circle markers for each feature using the map function
17+
18+
let earthquakesMarkers = earthquakeData.map((feature) =>
19+
L.circle([feature.geometry.coordinates[1], feature.geometry.coordinates[0]], {
20+
radius: radius(feature.properties.mag),
21+
stroke: true,
22+
color: color(feature.geometry.coordinates[2]),
23+
opacity: 1,
24+
weight: 0.5,
25+
fill: true,
26+
fillColor: color(feature.geometry.coordinates[2]),
27+
fillOpacity: 0.60
28+
})
29+
// Give each feature a popup describing the place and time of the earthquake
30+
.bindPopup(`<strong>Magnitud:</strong> ${feature.properties.mag} Ritcher||
31+
<strong>Depth:</strong> ${feature.geometry.coordinates[2]} km <br>
32+
${feature.properties.place}<br>
33+
Date: ${new Date(feature.properties.time)}<br>
34+
`)
35+
36+
)
37+
// // Create a layer containing the features array on the earthquakeData object
38+
let earthquakes = L.layerGroup(earthquakesMarkers);
39+
40+
createMap(earthquakes);
41+
}
42+
43+
function createMap(earthquakes) {
44+
// Create our map, giving it the streetmap and earthquakes layers to display on load
45+
let myMap = L.map("map", {
46+
center: [
47+
// 37.09, -95.71
48+
15,0
49+
],
50+
zoom: 3,
51+
layers: [earthquakes]
52+
53+
});
54+
// Define maps
55+
L.tileLayer("https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}", {
56+
attribution: "© <a href='https://www.mapbox.com/about/maps/'>Mapbox</a> © <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> <strong><a href='https://www.mapbox.com/map-feedback/' target='_blank'>Improve this map</a></strong>",
57+
tileSize: 512,
58+
maxZoom: 18,
59+
zoomOffset: -1,
60+
id: "mapbox/satellite-v9",
61+
accessToken: API_KEY,
62+
"terrain": {
63+
"source": "mapbox-raster-dem",
64+
"exaggeration": 5,
65+
}
66+
}).addTo(myMap);
67+
68+
69+
70+
71+
// Set up the legend
72+
let legend = L.control({ position: "bottomright" });
73+
legend.onAdd = function () {
74+
let div = L.DomUtil.create("div", "info legend");
75+
let limits = [0, 10, 25, 50, 100];
76+
let colors = ['#253494','#2c7fb8', '#41b6c4', '#a1dab4','#ffffcc'];
77+
let labels = [];
78+
79+
// Add min & max
80+
let legendInfo = "<h1>Depth</h1>" +
81+
"<div class=\"labels\">" +
82+
"<div class=\"min\">" + limits[0]+' km'+ "</div>" +
83+
"<div class=\"max\">" + ">"+ limits[limits.length - 1]+" km" + "</div>" +
84+
"</div>";
85+
86+
div.innerHTML = legendInfo;
87+
88+
limits.forEach(function (limit, index) {
89+
labels.push("<li style=\"background-color: " + colors[index] + "\"></li>");
90+
});
91+
92+
div.innerHTML += "<ul>" + labels.join("") + "</ul>";
93+
return div;
94+
};
95+
96+
// Adding legend to the map
97+
legend.addTo(myMap);
98+
};
99+
100+
// Earthquake magnitud scale: => http://www.geo.mtu.edu/UPSeis/magnitude.html -- also --
101+
102+
// Ritcher Scale
103+
// 2.5 or less Usually not felt, but can be recorded by seismograph
104+
// 2.5 to 5.4 Often felt, but only causes minor damage.
105+
// 5.5 to 6.0 Slight damage to buildings and other structures.
106+
// 6.1 to 6.9 May cause a lot of damage in very populated areas.
107+
// 7.0 to 7.9 Major earthquake. Serious damage.
108+
// 8.0 or greater Great earthquake. Can totally destroy communities near the epicenter.
109+
110+
// Create a function to get the magnitude
111+
function radius(mag) {
112+
//return mag * 30000
113+
if (mag < 5.5) {
114+
return mag * 30000
115+
}
116+
else if (mag < 6.1) {
117+
return mag * 35000
118+
}
119+
else if (mag < 7) {
120+
return mag * 40000
121+
}
122+
else if (mag < 8) {
123+
return mag * 45000
124+
}
125+
else {
126+
return mag * 50000
127+
}
128+
}
129+
130+
131+
// Although the assignment asks me to make the color darker if the earthquake is deeper,
132+
// since the closer to the surface the more intense and dangerous is the earthquake, I've decided to invert that order. For more info:
133+
//https://www.usgs.gov/natural-hazards/earthquake-hazards/science/earthquake-magnitude-energy-release-and-shaking-intensity?qt-science_center_objects=0#qt-science_center_objects
134+
// color scale from Color Brewer 2.0: https://colorbrewer2.org/#type=sequential&scheme=YlGnBu&n=5
135+
// https://www.usgs.gov/faqs/what-does-it-mean-earthquake-occurred-a-depth-0-km-how-can-earthquake-have-a-negative-depth?qt-news_science_products=0#qt-news_science_products
136+
137+
// #ffffcc
138+
// #a1dab4
139+
// #41b6c4
140+
// #2c7fb8
141+
// #253494
142+
143+
// define a function to get the color depending on the depth
144+
// the steps are related to the Earth's crust layers https://en.wikipedia.org/wiki/Structure_of_Earth
145+
function color(depth) {
146+
// let color = ""
147+
148+
if (depth > 220) {
149+
return "#ffffcc"
150+
} // step 1: mantle, Mesospheric mantle
151+
else if (depth > 80) {
152+
return "#a1dab4"
153+
} // step 2: mantle, Asthenosphere
154+
else if (depth > 20) {
155+
return "#41b6c4"
156+
}// step 3: LID
157+
else if (depth > 10) {
158+
return "#2c7fb8"
159+
}// step 4: lower crust
160+
else {
161+
return "#253494"
162+
}// step 5: upper crust
163+
}
164+
165+
166+
// Luis Fernando Ruiz Lopez
167+
// Rice University Data Analysis and Visualization Boot Camp

‎Level1/static/js/logic.js

+247
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
// Store our API endpoint inside queryUrl
2+
let earthquakesUrl = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_month.geojson"
3+
let platesUrl = "https://raw.githubusercontent.com/fraxen/tectonicplates/master/GeoJSON/PB2002_boundaries.json"
4+
// https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2014-01-01&endtime=+2014-01-02&maxlongitude=-69.52148437&minlongitude=-123.83789062&maxlatitude=48.74894534&minlatitude=25.16517337
5+
6+
// Perform a GET request to the query URL
7+
d3.json(earthquakesUrl).then(data => {
8+
// Perform a GET request to the query URL
9+
d3.json(platesUrl).then(function (json) {
10+
11+
let earthquakeData = data.features;
12+
let platesData = json.features
13+
14+
// Once we get a response, send the data.features object to the createFeatures function
15+
createFeatures(earthquakeData, platesData);
16+
//preventDefault();
17+
18+
});
19+
});
20+
21+
// Define a function we want to run once for each feature in the features array
22+
function createFeatures(earthquakeData, platesData) {
23+
24+
// Create circle markers for each feature using the map function
25+
26+
let earthquakesMarkers = earthquakeData.map((feature) =>
27+
L.circle([feature.geometry.coordinates[1], feature.geometry.coordinates[0]], {
28+
radius: radius(feature.properties.mag),
29+
stroke: true,
30+
color: color(feature.geometry.coordinates[2]),
31+
opacity: 1,
32+
weight: 0.5,
33+
fill: true,
34+
fillColor: color(feature.geometry.coordinates[2]),
35+
fillOpacity: 0.60
36+
})
37+
// Give each feature a popup describing the place and time of the earthquake
38+
.bindPopup(`<strong>Magnitud:</strong> ${feature.properties.mag} Ritcher||
39+
<strong>Depth:</strong> ${feature.geometry.coordinates[2]} km <br>
40+
${feature.properties.place}<br>
41+
Date: ${new Date(feature.properties.time)}<br>
42+
`),
43+
44+
45+
)
46+
47+
// // Create a layer containing the features array on the earthquakeData object
48+
let earthquakes = L.layerGroup(earthquakesMarkers)
49+
50+
51+
// create line function for the Tectonic plates
52+
53+
function platesLine(feature, layer) {
54+
L.polyline(feature.geometry.coordinates)
55+
};
56+
// // Create a GeoJSON layer containing the features array on the PlatesData object
57+
58+
let tectonicPlates = L.geoJSON(platesData, {
59+
onEachFeature: platesLine,
60+
style: {
61+
color: 'orange',
62+
opacity: 0.8
63+
}
64+
})
65+
66+
// Sending our earthquakes and tectonicPlates layers to the createMap function
67+
createMap(earthquakes, tectonicPlates);
68+
}
69+
70+
function createMap(earthquakes, tectonicPlates) {
71+
72+
// Define maps
73+
let satelliteMap = L.tileLayer("https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}", {
74+
attribution: "© <a href='https://www.mapbox.com/about/maps/'>Mapbox</a> © <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> <strong><a href='https://www.mapbox.com/map-feedback/' target='_blank'>Improve this map</a></strong>",
75+
tileSize: 512,
76+
maxZoom: 18,
77+
zoomOffset: -1,
78+
id: "mapbox/satellite-v9",
79+
accessToken: API_KEY,
80+
"terrain": {
81+
"source": "mapbox-raster-dem",
82+
"exaggeration": 5,
83+
}
84+
});
85+
86+
let streetMap = L.tileLayer("https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}", {
87+
attribution: "© <a href='https://www.mapbox.com/about/maps/'>Mapbox</a> © <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> <strong><a href='https://www.mapbox.com/map-feedback/' target='_blank'>Improve this map</a></strong>",
88+
tileSize: 500,
89+
maxZoom: 18,
90+
zoomOffset: -1,
91+
id: "mapbox/streets-v11",
92+
accessToken: API_KEY
93+
});
94+
95+
let lightMap = L.tileLayer("https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}", {
96+
attribution: "© <a href='https://www.mapbox.com/about/maps/'>Mapbox</a> © <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> <strong><a href='https://www.mapbox.com/map-feedback/' target='_blank'>Improve this map</a></strong>",
97+
tileSize: 512,
98+
maxZoom: 18,
99+
zoomOffset: -1,
100+
id: "mapbox/light-v10",
101+
accessToken: API_KEY
102+
});
103+
104+
let outdoorsMap = L.tileLayer("https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}", {
105+
attribution: "© <a href='https://www.mapbox.com/about/maps/'>Mapbox</a> © <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> <strong><a href='https://www.mapbox.com/map-feedback/' target='_blank'>Improve this map</a></strong>",
106+
tileSize: 512,
107+
maxZoom: 18,
108+
zoomOffset: -1,
109+
id: "mapbox/outdoors-v11",
110+
accessToken: API_KEY
111+
});
112+
113+
let darkMap = L.tileLayer("https://api.mapbox.com/styles/v1/mapbox/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}", {
114+
attribution: "Map data &copy; <a href=\"https://www.openstreetmap.org/\">OpenStreetMap</a> contributors, <a href=\"https://creativecommons.org/licenses/by-sa/2.0/\">CC-BY-SA</a>, Imagery © <a href=\"https://www.mapbox.com/\">Mapbox</a>",
115+
maxZoom: 18,
116+
id: "dark-v10",
117+
accessToken: API_KEY
118+
});
119+
120+
// Define a baseMaps object to hold our base layers
121+
let baseMaps = {
122+
"Satellite": satelliteMap,
123+
"Street Map": streetMap,
124+
"Light Map": lightMap,
125+
"Outdoors Map": outdoorsMap,
126+
"Dark Map": darkMap,
127+
};
128+
129+
// Create overlay object to hold our overlay layer
130+
let overlayMaps = {
131+
"Earthquakes": earthquakes,
132+
"Tectonic Plates": tectonicPlates,
133+
};
134+
135+
// Create our map, giving it the streetmap and earthquakes layers to display on load
136+
let myMap = L.map("map", {
137+
center: [
138+
// 37.09, -95.71
139+
15,0
140+
],
141+
zoom: 3,
142+
layers: [satelliteMap, earthquakes, tectonicPlates]
143+
});
144+
145+
// Create a layer control
146+
// Pass in our baseMaps and overlayMaps
147+
// Add the layer control to the map
148+
L.control.layers(baseMaps, overlayMaps, {
149+
collapsed: true
150+
}).addTo(myMap);
151+
152+
// Set up the legend
153+
let legend = L.control({ position: "bottomright" });
154+
legend.onAdd = function () {
155+
let div = L.DomUtil.create("div", "info legend");
156+
let limits = [0, 10, 25, 50, 100];
157+
let colors = ['#253494','#2c7fb8', '#41b6c4', '#a1dab4','#ffffcc'];
158+
let labels = [];
159+
160+
// Add min & max
161+
let legendInfo = "<h1>Depth</h1>" +
162+
"<div class=\"labels\">" +
163+
"<div class=\"min\">" + limits[0]+' km'+ "</div>" +
164+
"<div class=\"max\">" + ">"+ limits[limits.length - 1]+" km" + "</div>" +
165+
"</div>";
166+
167+
div.innerHTML = legendInfo;
168+
169+
limits.forEach(function (limit, index) {
170+
labels.push("<li style=\"background-color: " + colors[index] + "\"></li>");
171+
});
172+
173+
div.innerHTML += "<ul>" + labels.join("") + "</ul>";
174+
return div;
175+
};
176+
177+
// Adding legend to the map
178+
legend.addTo(myMap);
179+
};
180+
181+
// Earthquake magnitud scale: => http://www.geo.mtu.edu/UPSeis/magnitude.html -- also --
182+
183+
// Ritcher Scale
184+
// 2.5 or less Usually not felt, but can be recorded by seismograph
185+
// 2.5 to 5.4 Often felt, but only causes minor damage.
186+
// 5.5 to 6.0 Slight damage to buildings and other structures.
187+
// 6.1 to 6.9 May cause a lot of damage in very populated areas.
188+
// 7.0 to 7.9 Major earthquake. Serious damage.
189+
// 8.0 or greater Great earthquake. Can totally destroy communities near the epicenter.
190+
191+
// Create a function to get the magnitude
192+
function radius(mag) {
193+
//return mag * 30000
194+
if (mag < 5.5) {
195+
return mag * 30000
196+
}
197+
else if (mag < 6.1) {
198+
return mag * 35000
199+
}
200+
else if (mag < 7) {
201+
return mag * 40000
202+
}
203+
else if (mag < 8) {
204+
return mag * 45000
205+
}
206+
else {
207+
return mag * 50000
208+
}
209+
}
210+
211+
212+
// Although the assignment asks me to make the color darker if the earthquake is deeper,
213+
// since the closer to the surface the more intense and dangerous is the earthquake, I've decided to invert that order. For more info:
214+
//https://www.usgs.gov/natural-hazards/earthquake-hazards/science/earthquake-magnitude-energy-release-and-shaking-intensity?qt-science_center_objects=0#qt-science_center_objects
215+
// color scale from Color Brewer 2.0: https://colorbrewer2.org/#type=sequential&scheme=YlGnBu&n=5
216+
// https://www.usgs.gov/faqs/what-does-it-mean-earthquake-occurred-a-depth-0-km-how-can-earthquake-have-a-negative-depth?qt-news_science_products=0#qt-news_science_products
217+
218+
// #ffffcc
219+
// #a1dab4
220+
// #41b6c4
221+
// #2c7fb8
222+
// #253494
223+
224+
// define a function to get the color depending on the depth
225+
// the steps are related to the Earth's crust layers https://en.wikipedia.org/wiki/Structure_of_Earth
226+
function color(depth) {
227+
// let color = ""
228+
229+
if (depth > 220) {
230+
return "#ffffcc"
231+
} // step 1: mantle, Mesospheric mantle
232+
else if (depth > 80) {
233+
return "#a1dab4"
234+
} // step 2: mantle, Asthenosphere
235+
else if (depth > 20) {
236+
return "#41b6c4"
237+
}// step 3: LID
238+
else if (depth > 10) {
239+
return "#2c7fb8"
240+
}// step 4: lower crust
241+
else {
242+
return "#253494"
243+
}// step 5: upper crust
244+
}
245+
246+
// Luis Fernando Ruiz Lopez
247+
// Rice University Data Analysis and Visualization Boot Camp

‎README.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ Your first task is to visualize an earthquake data set.
4242

4343

4444
Solutions:
45-
[GitHub](https://github.com/LF-Ruiz/leaflet-challenge/blob/main/static/js/logic.js)
45+
[GitHub](https://github.com/LF-Ruiz/leaflet-challenge/blob/main/static/js/stepOne.js)
46+
47+
![StepOne](./images/level1.jpg)
4648

4749
### Level 2: More Data (Optional)
4850

@@ -56,4 +58,4 @@ The USGS wants you to plot a second data set on your map to illustrate the relat
5658

5759
Solutions: [GitHub](https://github.com/LF-Ruiz/leaflet-challenge/blob/main/static/js/logic.js)-[Deployed Page](https://lf-ruiz.github.io/leaflet-challenge/)
5860

59-
![StepTwoPicture](./images/stepTwo.jpg)
61+
![LevelTwoPicture](./images/level2.jpg)

‎index.html

+10-3
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,20 @@
2020

2121
<body>
2222
<!-- <div class= 'container'> -->
23-
<!-- <div class= 'row'> -->
24-
<h1 class = "title"> Earthquakes with magnitud more than 2.5 Ritcher Scale in the last month</h1>
25-
</div>
23+
<div>
24+
<h1 class = "title"> Earthquakes with magnitud
25+
more than 2.5 Ritcher Scale in the last month
26+
<a href="Level1/index.html" class="btn btn-primary">Go To Level 1</a>
27+
</h1>
28+
29+
</div>
2630

2731
<!-- The div that holds our map -->
2832
<!-- <section> -->
2933
<div id="map" class = row></div>
3034
<!-- </section> -->
3135
<!-- </div> -->
36+
3237
<!-- Leaflet JS -->
3338
<script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"
3439
integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew=="
@@ -40,6 +45,8 @@ <h1 class = "title"> Earthquakes with magnitud more than 2.5 Ritcher Scale in th
4045
<script type="text/javascript" src="static/js/config.js"></script>
4146
<!-- Our JavaScript -->
4247
<script type="text/javascript" src="static/js/logic.js"></script>
48+
<!-- <script type="text/javascript" src="static/js/level1.js"></script> -->
49+
4350
<!-- Leaflet heatmap plugin-->
4451
<script type="text/javascript" src="static/js/leaflet-heat.js"></script>
4552
</body>

‎static/css/style.css

+13-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@ body {
22
padding: 0;
33
margin: 0;
44
}
5+
.link {
6+
font-size: 8px;
7+
}
8+
.btn-primary {
9+
background-color: rgba(187, 255, 255, 0.272);
10+
font-style: normal;
11+
color: black;
12+
font-family: Arial, Helvetica, sans-serif;
13+
font-weight: 900;
14+
font-size: 15px;
15+
}
516

617
.title{
718
font-size: 25px;
@@ -57,4 +68,5 @@ html {
5768

5869
h1 {
5970
text-align: center;
60-
}
71+
}
72+

‎static/js/level1.js

+167
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
// Store our API endpoint inside queryUrl
2+
let earthquakesUrl = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_month.geojson"
3+
// https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2014-01-01&endtime=+2014-01-02&maxlongitude=-69.52148437&minlongitude=-123.83789062&maxlatitude=48.74894534&minlatitude=25.16517337
4+
5+
// Perform a GET request to the query URL
6+
d3.json(earthquakesUrl).then(data => {
7+
// define earthquake Data
8+
let earthquakeData = data.features;
9+
// Once we get a response, send the data.features object to the createFeatures function
10+
createFeatures(earthquakeData);
11+
});
12+
13+
// Define a function we want to run once for each feature in the features array
14+
function createFeatures(earthquakeData) {
15+
16+
// Create circle markers for each feature using the map function
17+
18+
let earthquakesMarkers = earthquakeData.map((feature) =>
19+
L.circle([feature.geometry.coordinates[1], feature.geometry.coordinates[0]], {
20+
radius: radius(feature.properties.mag),
21+
stroke: true,
22+
color: color(feature.geometry.coordinates[2]),
23+
opacity: 1,
24+
weight: 0.5,
25+
fill: true,
26+
fillColor: color(feature.geometry.coordinates[2]),
27+
fillOpacity: 0.60
28+
})
29+
// Give each feature a popup describing the place and time of the earthquake
30+
.bindPopup(`<strong>Magnitud:</strong> ${feature.properties.mag} Ritcher||
31+
<strong>Depth:</strong> ${feature.geometry.coordinates[2]} km <br>
32+
${feature.properties.place}<br>
33+
Date: ${new Date(feature.properties.time)}<br>
34+
`)
35+
36+
)
37+
// // Create a layer containing the features array on the earthquakeData object
38+
let earthquakes = L.layerGroup(earthquakesMarkers);
39+
40+
createMap(earthquakes);
41+
}
42+
43+
function createMap(earthquakes) {
44+
// Create our map, giving it the streetmap and earthquakes layers to display on load
45+
let myMap = L.map("map", {
46+
center: [
47+
// 37.09, -95.71
48+
15,0
49+
],
50+
zoom: 3,
51+
layers: [earthquakes]
52+
53+
});
54+
// Define maps
55+
L.tileLayer("https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}", {
56+
attribution: "© <a href='https://www.mapbox.com/about/maps/'>Mapbox</a> © <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> <strong><a href='https://www.mapbox.com/map-feedback/' target='_blank'>Improve this map</a></strong>",
57+
tileSize: 512,
58+
maxZoom: 18,
59+
zoomOffset: -1,
60+
id: "mapbox/satellite-v9",
61+
accessToken: API_KEY,
62+
"terrain": {
63+
"source": "mapbox-raster-dem",
64+
"exaggeration": 5,
65+
}
66+
}).addTo(myMap);
67+
68+
69+
70+
71+
// Set up the legend
72+
let legend = L.control({ position: "bottomright" });
73+
legend.onAdd = function () {
74+
let div = L.DomUtil.create("div", "info legend");
75+
let limits = [0, 10, 25, 50, 100];
76+
let colors = ['#253494','#2c7fb8', '#41b6c4', '#a1dab4','#ffffcc'];
77+
let labels = [];
78+
79+
// Add min & max
80+
let legendInfo = "<h1>Depth</h1>" +
81+
"<div class=\"labels\">" +
82+
"<div class=\"min\">" + limits[0]+' km'+ "</div>" +
83+
"<div class=\"max\">" + ">"+ limits[limits.length - 1]+" km" + "</div>" +
84+
"</div>";
85+
86+
div.innerHTML = legendInfo;
87+
88+
limits.forEach(function (limit, index) {
89+
labels.push("<li style=\"background-color: " + colors[index] + "\"></li>");
90+
});
91+
92+
div.innerHTML += "<ul>" + labels.join("") + "</ul>";
93+
return div;
94+
};
95+
96+
// Adding legend to the map
97+
legend.addTo(myMap);
98+
};
99+
100+
// Earthquake magnitud scale: => http://www.geo.mtu.edu/UPSeis/magnitude.html -- also --
101+
102+
// Ritcher Scale
103+
// 2.5 or less Usually not felt, but can be recorded by seismograph
104+
// 2.5 to 5.4 Often felt, but only causes minor damage.
105+
// 5.5 to 6.0 Slight damage to buildings and other structures.
106+
// 6.1 to 6.9 May cause a lot of damage in very populated areas.
107+
// 7.0 to 7.9 Major earthquake. Serious damage.
108+
// 8.0 or greater Great earthquake. Can totally destroy communities near the epicenter.
109+
110+
// Create a function to get the magnitude
111+
function radius(mag) {
112+
//return mag * 30000
113+
if (mag < 5.5) {
114+
return mag * 30000
115+
}
116+
else if (mag < 6.1) {
117+
return mag * 35000
118+
}
119+
else if (mag < 7) {
120+
return mag * 40000
121+
}
122+
else if (mag < 8) {
123+
return mag * 45000
124+
}
125+
else {
126+
return mag * 50000
127+
}
128+
}
129+
130+
131+
// Although the assignment asks me to make the color darker if the earthquake is deeper,
132+
// since the closer to the surface the more intense and dangerous is the earthquake, I've decided to invert that order. For more info:
133+
//https://www.usgs.gov/natural-hazards/earthquake-hazards/science/earthquake-magnitude-energy-release-and-shaking-intensity?qt-science_center_objects=0#qt-science_center_objects
134+
// color scale from Color Brewer 2.0: https://colorbrewer2.org/#type=sequential&scheme=YlGnBu&n=5
135+
// https://www.usgs.gov/faqs/what-does-it-mean-earthquake-occurred-a-depth-0-km-how-can-earthquake-have-a-negative-depth?qt-news_science_products=0#qt-news_science_products
136+
137+
// #ffffcc
138+
// #a1dab4
139+
// #41b6c4
140+
// #2c7fb8
141+
// #253494
142+
143+
// define a function to get the color depending on the depth
144+
// the steps are related to the Earth's crust layers https://en.wikipedia.org/wiki/Structure_of_Earth
145+
function color(depth) {
146+
// let color = ""
147+
148+
if (depth > 220) {
149+
return "#ffffcc"
150+
} // step 1: mantle, Mesospheric mantle
151+
else if (depth > 80) {
152+
return "#a1dab4"
153+
} // step 2: mantle, Asthenosphere
154+
else if (depth > 20) {
155+
return "#41b6c4"
156+
}// step 3: LID
157+
else if (depth > 10) {
158+
return "#2c7fb8"
159+
}// step 4: lower crust
160+
else {
161+
return "#253494"
162+
}// step 5: upper crust
163+
}
164+
165+
166+
// Luis Fernando Ruiz Lopez
167+
// Rice University Data Analysis and Visualization Boot Camp

‎static/js/logic.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -241,4 +241,7 @@ function color(depth) {
241241
else {
242242
return "#253494"
243243
}// step 5: upper crust
244-
}
244+
}
245+
246+
// Luis Fernando Ruiz Lopez
247+
// Rice University Data Analysis and Visualization Boot Camp

0 commit comments

Comments
 (0)
Please sign in to comment.