Skip to content

Commit

Permalink
Merge pull request #63 from wmo-raf/dev
Browse files Browse the repository at this point in the history
Updates and Bug Fixes
  • Loading branch information
erick-otenyo authored Jan 30, 2024
2 parents 414c1c2 + 2a2ab34 commit dec999c
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 128 deletions.
3 changes: 3 additions & 0 deletions pages/cap/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"color": "#fe9900",
"background_color": "#fff9f2",
"border_color": "#9a6100",
"icon_color": "#0a0a0a",
"severity": "Severe",
"id": 3
},
Expand All @@ -21,6 +22,7 @@
"color": "#ffff00",
"background_color": "#fffdf1",
"border_color": "#938616",
"icon_color": "#0a0a0a",
"severity": "Moderate",
"id": 2
},
Expand All @@ -29,6 +31,7 @@
"color": "#03ffff",
"background_color": "#fffdf1",
"border_color": "#938616",
"icon_color": "#0a0a0a",
"severity": "Minor",
"id": 1
}
Expand Down
10 changes: 10 additions & 0 deletions pages/cap/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,16 @@ class CapAlertPage(MetadataPageMixin, AbstractCapAlertPage):
*AbstractCapAlertPage.content_panels
]

@cached_property
def feature_collection(self):
fc = {"type": "FeatureCollection", "features": []}
for info in self.info:
if info.value.features:
for feature in info.value.features:
feature.get("properties", {}).update({"info-id": info.id})
fc["features"].append(feature)
return fc

@cached_property
def xml_link(self):
return reverse("cap_alert_detail", args=(self.identifier,))
Expand Down
289 changes: 163 additions & 126 deletions pages/cap/templates/cap/alert_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,24 @@ <h2 class="title">
</div>
</div>
<div class="column is-three-fifths-widescreen is-full-touch featured-item-detail">
<div class="tabs">
<div class="tabs is-boxed ">
<ul>
{% if page.infos|length > 0 %}
{% for item in page.infos %}
<li class="{% if forloop.first %}is-active {% endif %}"
data-target="{{ item.info.value.event }}-{{ forloop.counter }}">
<a>{{ item.info.value.event |truncatechars:20}}</a>
data-target="{{ item.info.id }}">
<a>
{% if item.info.value.event_icon %}
<span class="alert-icon-wrapper"
style="margin-right: 10px;background-color: {{ item.severity.color }};border-color: {{ item.severity.border_color }};
{% if item.severity.icon_color %}color:{{ item.severity.icon_color }};{% endif %} ">
{% svg_icon name=item.info.value.event_icon %}
</span>
{% endif %}
<span style="margin-right: 10px">
{{ item.info.value.event |truncatechars:20}}
</span>
</a>
</li>
{% endfor %}
{% endif %}
Expand All @@ -116,7 +127,7 @@ <h2 class="title">
<div id="tab-content">
{% for alert_info in page.infos %}
<div class="featured-item-body {% if not forloop.first %}is-hidden{% endif %}"
id="{{ alert_info.info.value.event }}-{{ forloop.counter }}">
id="{{ alert_info.info.id }}">
{% with item=alert_info.info %}
<h3 class="featured-item-title">
{% if item.value.headline %}
Expand Down Expand Up @@ -287,147 +298,173 @@ <h3 class="featured-item-title">
<script src="https://unpkg.com/@turf/turf@6.5.0/turf.min.js"></script>
<script>

const tabs = document.querySelectorAll('.tabs li')
const tabContentBoxes = document.querySelectorAll('#tab-content > div')
document.addEventListener('DOMContentLoaded', () => {
// Tabs

tabs.forEach((tab) => {
tab.addEventListener('click', () => {
tabs.forEach(item => item.classList.remove('is-active'))
const tabs = document.querySelectorAll('.tabs li')
const tabContentBoxes = document.querySelectorAll('#tab-content > div')

tab.classList.add('is-active')
tabs.forEach((tab) => {
tab.addEventListener('click', () => {
tabs.forEach(item => item.classList.remove('is-active'))

const target = tab.dataset.target;
tabContentBoxes.forEach(box => {
if (box.getAttribute('id') === target) {
box.classList.remove('is-hidden')
} else {
box.classList.add('is-hidden')
tab.classList.add('is-active')

}
const target = tab.dataset.target;

// filter map layer
detail_map.setFilter('alert-areas-layer', ['==', 'info-id', target]);


tabContentBoxes.forEach(box => {
if (box.getAttribute('id') === target) {
box.classList.remove('is-hidden')
} else {
box.classList.add('is-hidden')
}
})
})
})
})
// alert area as geojson
const geojson = {{ page.geojson|safe }};
// alert area bounds
const bounds = {{ page.bounds|safe }};

// default MapLibre style
const defaultStyle = {
'version': 8,
'sources': {
'carto-dark': {
'type': 'raster',
'tiles': [
"https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png",
"https://b.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png",
"https://c.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png",
"https://d.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png"
]
},
'carto-light': {
'type': 'raster',
'tiles': [
"https://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png",
"https://b.basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png",
"https://c.basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png",
"https://d.basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png"
]
},
'wikimedia': {
'type': 'raster',
'tiles': [
"https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png"
]

let initialFilter;
// get current active tab
const activeTab = document.querySelector('.tabs li.is-active');
if (activeTab) {
const target = activeTab.dataset.target;
if (target) {
// filter map layer by active info id
initialFilter = ['==', 'info-id', target];
}
},
'layers': [{
'id': 'carto-light-layer',
'source': 'carto-light',
}


'type': 'raster',
'minzoom': 0,
'maxzoom': 22
}]
}
// alert area as geojson
const geojson = {{ page.geojson|safe }};
// alert area bounds
const bounds = {{ page.bounds|safe }};

const detail_map = new maplibregl.Map({
container: "cap-map", // container ID
style: defaultStyle,
center: [30.019531249998607, 16.130262012034265], // starting position [lng, lat]
zoom: 4.2, // starting zoom
scrollZoom: false,
});
// default MapLibre style
const defaultStyle = {
'version': 8,
'sources': {
'carto-dark': {
'type': 'raster',
'tiles': [
"https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png",
"https://b.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png",
"https://c.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png",
"https://d.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png"
]
},
'carto-light': {
'type': 'raster',
'tiles': [
"https://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png",
"https://b.basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png",
"https://c.basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png",
"https://d.basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png"
]
},
'wikimedia': {
'type': 'raster',
'tiles': [
"https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png"
]
}
},
'layers': [{
'id': 'carto-light-layer',
'source': 'carto-light',

// add zoom control
detail_map.addControl(
new maplibregl.NavigationControl({
visualizePitch: true,
showZoom: true,
showCompass: true,
})
);

detail_map.on("load", () => {
detail_map.addSource("alert-areas", {
type: "geojson",
data: geojson,
'type': 'raster',
'minzoom': 0,
'maxzoom': 22
}]
}

const detail_map = new maplibregl.Map({
container: "cap-map", // container ID
style: defaultStyle,
center: [30.019531249998607, 16.130262012034265], // starting position [lng, lat]
zoom: 4.2, // starting zoom
scrollZoom: false,
});

detail_map.addLayer({
id: "alert-areas-layer",
type: "fill",
source: "alert-areas",
paint: {
"fill-color": [
"case",
["==", ["get", "severity"], "Extreme"],
"#d72f2a",
["==", ["get", "severity"], "Severe"],
"#f89904",
["==", ["get", "severity"], "Moderate"],
"#e4e616",
["==", ["get", "severity"], "Minor"],
"#53ffff",
["==", ["get", "severity"], "Unknown"],
"#3366ff",
"black",
],
"fill-opacity": 0.7,
"fill-outline-color": "#000",
// add zoom control
detail_map.addControl(
new maplibregl.NavigationControl({
visualizePitch: true,
showZoom: true,
showCompass: true,
})
);

},
});
// fit to bounds
if (bounds) {
const bbox = [[bounds[0], bounds[1]], [bounds[2], bounds[3]]]
detail_map.fitBounds(bbox, {padding: 20})
}
// When a click event occurs on a feature in the places layer, open a popup at the
// location of the feature, with description HTML from its properties.
detail_map.on("click", "alert-areas-layer", (e) => {
// Copy coordinates array.
const description = e.features[0].properties.areaDesc;

new maplibregl.Popup()
.setLngLat(e.lngLat)
.setHTML(`<h4>${description}</h4>`)
.addTo(detail_map);
});
detail_map.on("load", () => {

// Change the cursor to a pointer when the mouse is over the places layer.
detail_map.on("mouseenter", "alert-areas-layer", () => {
detail_map.getCanvas().style.cursor = "pointer";
});
detail_map.addSource("alert-areas", {
type: "geojson",
data: geojson,
});

// Change it back to a pointer when it leaves.
detail_map.on("mouseleave", "alert-areas-layer", () => {
detail_map.getCanvas().style.cursor = "";
});
});
const filterConfig = {}
if (initialFilter) {
filterConfig['filter'] = initialFilter;
}

detail_map.addLayer({
id: "alert-areas-layer",
type: "fill",
source: "alert-areas",
...filterConfig,
paint: {
"fill-color": [
"case",
["==", ["get", "severity"], "Extreme"],
"#d72f2a",
["==", ["get", "severity"], "Severe"],
"#f89904",
["==", ["get", "severity"], "Moderate"],
"#e4e616",
["==", ["get", "severity"], "Minor"],
"#53ffff",
["==", ["get", "severity"], "Unknown"],
"#3366ff",
"black",
],
"fill-opacity": 0.7,
"fill-outline-color": "#000",

},
});
// fit to bounds
if (bounds) {
const bbox = [[bounds[0], bounds[1]], [bounds[2], bounds[3]]]
detail_map.fitBounds(bbox, {padding: 20})
}
// When a click event occurs on a feature in the places layer, open a popup at the
// location of the feature, with description HTML from its properties.
detail_map.on("click", "alert-areas-layer", (e) => {
// Copy coordinates array.
const description = e.features[0].properties.areaDesc;

new maplibregl.Popup()
.setLngLat(e.lngLat)
.setHTML(`<h4>${description}</h4>`)
.addTo(detail_map);
});

// Change the cursor to a pointer when the mouse is over the places layer.
detail_map.on("mouseenter", "alert-areas-layer", () => {
detail_map.getCanvas().style.cursor = "pointer";
});

// Change it back to a pointer when it leaves.
detail_map.on("mouseleave", "alert-areas-layer", () => {
detail_map.getCanvas().style.cursor = "";
});
});
});
</script>


Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ attrs==23.1.0
beautifulsoup4==4.9.3
billiard==3.6.4.0
cachetools==5.3.0
capeditor==0.4.5
capeditor==0.4.6
Cartopy==0.21.1
celery==5.2.7
certifi==2023.07.22
Expand Down Expand Up @@ -73,7 +73,7 @@ fonttools==4.39.4
forecastmanager==0.2.0
frozenlist==1.3.3
future==0.18.3
geomanager==0.3.8
geomanager==0.4.3
geopandas==0.13.0
google-api-core==2.11.0
google-api-python-client==2.79.0
Expand Down

0 comments on commit dec999c

Please sign in to comment.