diff --git a/django_project/core/settings/celery_config.py b/django_project/core/settings/celery_config.py
index 87dec8f9..954840c4 100644
--- a/django_project/core/settings/celery_config.py
+++ b/django_project/core/settings/celery_config.py
@@ -22,6 +22,7 @@
CELERY_DEFAULT_ROUTING_KEY = "default"
CELERY_CREATE_MISSING_QUEUES = True
CELERYD_CONCURRENCY = 1
+CELERYD_PREFETCH_MULTIPLIER = 1
CELERY_QUEUES = [
Queue('default', routing_key='default'),
diff --git a/django_project/realtime/migrations/0026_auto_20170209_1905.py b/django_project/realtime/migrations/0026_auto_20170209_1905.py
new file mode 100644
index 00000000..eb282059
--- /dev/null
+++ b/django_project/realtime/migrations/0026_auto_20170209_1905.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('realtime', '0025_auto_20170206_2046'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='ash',
+ name='impact_files',
+ field=models.FileField(help_text=b'Impact files processed zipped', upload_to=b'ash/impact_files/%Y/%m/%d', null=True, verbose_name=b'Impact Files', blank=True),
+ preserve_default=True,
+ ),
+ migrations.AddField(
+ model_name='earthquake',
+ name='mmi_output',
+ field=models.FileField(help_text=b'MMI related file, layers, and data, zipped.', upload_to=b'earthquake/mmi_output', null=True, verbose_name=b'MMI related file zipped', blank=True),
+ preserve_default=True,
+ ),
+ migrations.AlterField(
+ model_name='ash',
+ name='eruption_height',
+ field=models.IntegerField(default=0, verbose_name=b'Eruption height in metres'),
+ preserve_default=True,
+ ),
+ ]
diff --git a/django_project/realtime/migrations/0027_flood_data_source.py b/django_project/realtime/migrations/0027_flood_data_source.py
new file mode 100644
index 00000000..ab094f98
--- /dev/null
+++ b/django_project/realtime/migrations/0027_flood_data_source.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('realtime', '0026_auto_20170209_1905'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='flood',
+ name='data_source',
+ field=models.CharField(default=None, max_length=255, blank=True, help_text=b'The source of the hazard data used for analysis', null=True, verbose_name=b'The source of hazard data'),
+ preserve_default=True,
+ ),
+ ]
diff --git a/django_project/realtime/models/ash.py b/django_project/realtime/models/ash.py
index bd64d134..082fbc13 100644
--- a/django_project/realtime/models/ash.py
+++ b/django_project/realtime/models/ash.py
@@ -35,6 +35,13 @@ class Meta:
upload_to='ash/hazard_file/%Y/%m/%d',
blank=False
)
+ impact_files = models.FileField(
+ verbose_name='Impact Files',
+ help_text='Impact files processed zipped',
+ upload_to='ash/impact_files/%Y/%m/%d',
+ blank=True,
+ null=True
+ )
event_time = models.DateTimeField(
verbose_name='Event Date and Time',
help_text='The time the ash happened.',
@@ -67,6 +74,8 @@ def delete(self, using=None):
# delete all report
if self.hazard_file:
self.hazard_file.delete()
+ if self.impact_files:
+ self.impact_files.delete()
return super(Ash, self).delete(using=using)
diff --git a/django_project/realtime/models/earthquake.py b/django_project/realtime/models/earthquake.py
index 6a0eeab4..28876eea 100644
--- a/django_project/realtime/models/earthquake.py
+++ b/django_project/realtime/models/earthquake.py
@@ -22,6 +22,12 @@ class Meta:
upload_to='earthquake/grid',
blank=True,
null=True)
+ mmi_output = models.FileField(
+ verbose_name='MMI related file zipped',
+ help_text='MMI related file, layers, and data, zipped.',
+ upload_to='earthquake/mmi_output',
+ blank=True,
+ null=True)
magnitude = models.FloatField(
verbose_name='The magnitude',
help_text='The magnitude of the event.')
@@ -61,6 +67,8 @@ def delete(self, using=None):
# delete all report
if self.shake_grid:
self.shake_grid.delete()
+ if self.mmi_output:
+ self.mmi_output.delete()
for report in self.reports.all():
report.delete(using=using)
super(Earthquake, self).delete(using=using)
diff --git a/django_project/realtime/models/flood.py b/django_project/realtime/models/flood.py
index da5ffc48..348964a7 100644
--- a/django_project/realtime/models/flood.py
+++ b/django_project/realtime/models/flood.py
@@ -81,6 +81,13 @@ class Meta:
max_length=20,
unique=True,
blank=False)
+ data_source = models.CharField(
+ verbose_name='The source of hazard data',
+ help_text='The source of the hazard data used for analysis',
+ max_length=255,
+ blank=True,
+ null=True,
+ default=None)
time = models.DateTimeField(
verbose_name='Date and Time',
help_text='The time the flood reported.',
diff --git a/django_project/realtime/serializers/ash_serializer.py b/django_project/realtime/serializers/ash_serializer.py
index 6b1c875b..4705f86e 100644
--- a/django_project/realtime/serializers/ash_serializer.py
+++ b/django_project/realtime/serializers/ash_serializer.py
@@ -117,6 +117,8 @@ class Meta:
'url',
'id',
'volcano',
+ 'hazard_file',
+ 'impact_files',
'reports',
'event_time',
'task_status',
@@ -132,13 +134,32 @@ class AshGeoJsonSerializer(GeoFeatureModelSerializer):
def get_location(self, obj):
return obj.volcano.location
+ def get_event_id_formatted(self, serializer_field, obj):
+ """
+ :param serializer_field:
+ :type serializer_field: CustomSerializerMethodField
+ :param obj:
+ :type obj: Ash
+ :return:
+ """
+ dateformat = '%Y%m%d%H%M%S%z'
+ return '%s-%s' % (
+ obj.event_time.strftime(dateformat),
+ obj.volcano.volcano_name)
+
+ # auto bind to get_url method
+ event_id_formatted = CustomSerializerMethodField()
+
class Meta:
model = Ash
geo_field = 'location'
id = 'id',
fields = (
'id',
+ 'event_id_formatted',
'volcano',
+ 'hazard_file',
+ 'impact_files',
'event_time',
'alert_level',
'task_status',
diff --git a/django_project/realtime/serializers/earthquake_serializer.py b/django_project/realtime/serializers/earthquake_serializer.py
index ee2d910d..9adad04a 100644
--- a/django_project/realtime/serializers/earthquake_serializer.py
+++ b/django_project/realtime/serializers/earthquake_serializer.py
@@ -106,6 +106,7 @@ class Meta:
'url',
'shake_id',
'shake_grid',
+ 'mmi_output',
'magnitude',
'time',
'depth',
@@ -125,6 +126,7 @@ class Meta:
fields = (
'shake_id',
'shake_grid',
+ 'mmi_output',
'magnitude',
'time',
'depth',
diff --git a/django_project/realtime/serializers/flood_serializer.py b/django_project/realtime/serializers/flood_serializer.py
index 45a5252b..edce937a 100644
--- a/django_project/realtime/serializers/flood_serializer.py
+++ b/django_project/realtime/serializers/flood_serializer.py
@@ -139,6 +139,7 @@ class Meta:
fields = (
'url',
'event_id',
+ 'data_source',
'event_id_formatted',
'time',
'time_description',
diff --git a/django_project/realtime/signals/flood.py b/django_project/realtime/signals/flood.py
index 389cab57..34fc3c73 100644
--- a/django_project/realtime/signals/flood.py
+++ b/django_project/realtime/signals/flood.py
@@ -38,6 +38,6 @@ def flood_post_save(
chain(
process_hazard_layer.si(instance),
process_impact_layer.si(instance),
- recalculate_impact_info(instance))()
+ recalculate_impact_info.si(instance))()
except Exception as e:
LOGGER.exception(e)
diff --git a/django_project/realtime/static/realtime/css/realtime.css b/django_project/realtime/static/realtime/css/realtime.css
index 47017d54..0044d339 100644
--- a/django_project/realtime/static/realtime/css/realtime.css
+++ b/django_project/realtime/static/realtime/css/realtime.css
@@ -263,4 +263,12 @@ th.dynatable-head a, th.dynatable-head a:hover {
/* ******************** */
.timepicker-picker td.separator{
line-height: 54px;
-}
\ No newline at end of file
+}
+
+
+/* ******************** */
+/* Dropdown in table */
+/* ******************** */
+.btn-group .dropdown-menu{
+ position: absolute;
+}
diff --git a/django_project/realtime/static/realtime/js/ash/ash.js b/django_project/realtime/static/realtime/js/ash/ash.js
index bece2b3d..93c38b47 100644
--- a/django_project/realtime/static/realtime/js/ash/ash.js
+++ b/django_project/realtime/static/realtime/js/ash/ash.js
@@ -106,15 +106,15 @@ function createShowEventHandler(map, markers, map_events) {
/**
* Closure to create handler for showReport
- * use magic number 000 for url placeholder
+ * use magic number for url placeholder
*
- * @param {string} report_url A report url that contains shake_id placeholder
- * @return {function} Open the report based on shake_id in a new tab
+ * @param {string} report_url A report url that contains event_id placeholder
+ * @return {function} Open the report based on event_id in a new tab
*/
function createShowReportHandler(report_url) {
var showReportHandler = function (id) {
var url = report_url;
- // replace magic number 000 with shake_id
+ // replace magic number
function createFindWithId(id){
return function (event) {
return event.properties.id == id;
@@ -171,6 +171,54 @@ function createShowReportHandler(report_url) {
return showReportHandler;
}
+/**
+ * Closure to create handler for downloadReport
+ * use magic number for url placeholder
+ *
+ * @param {string} report_url A report url that contains event_id placeholder
+ * @return {function} Open the report based on event_id in a new tab
+ */
+function createDownloadReportHandler(report_url) {
+ var downloadReportHandler = function (id) {
+ var url = report_url;
+ // replace magic number 000 with shake_id
+ function createFindWithId(id){
+ return function (event) {
+ return event.properties.id == id;
+ }
+ }
+ var findWithId = createFindWithId(id);
+ var feature = event_json.features.find(findWithId);
+ var volcano_name = feature.properties.volcano.volcano_name;
+ var event_time = feature.properties.event_time;
+ var event_time_string = moment(event_time).format('YYYYMMDDHHmmssZZ');
+ var event_id_formatted = feature.properties.event_id_formatted;
+ var task_status = feature.properties.task_status;
+ if(task_status == 'PENDING'){
+ alert("Report is currently being generated. Refresh this page later.");
+ return;
+ }
+ else if(task_status == 'FAILED'){
+ alert("Report failed to generate.");
+ return;
+ }
+ url = url.replace('VOLCANOTEMPLATENAME', volcano_name)
+ .replace('1234567890123456789', event_time_string);
+ $.get(url, function (data) {
+ if (data && data.report_map) {
+ var pdf_url = data.report_map;
+ SaveToDisk(pdf_url, event_id_formatted+'-'+data.language+'.pdf');
+ }
+ }).fail(function(e){
+ console.log(e);
+ if(e.status == 404){
+ alert("No Report recorded for this event.");
+ }
+ });
+ };
+ return downloadReportHandler;
+}
+
/**
* Create Action Writer based on button_templates
@@ -200,17 +248,64 @@ function createActionRowWriter(button_templates, date_format) {
var $span = $('');
for (var i = 0; i < button_templates.length; i++) {
var button = button_templates[i];
- var $inner_button = $('');
- $inner_button.addClass('row-action-icon')
- $inner_button.addClass(button.css_class);
- $inner_button.attr('title', button.name);
- $inner_button.text(button.label);
- var $button = $('');
- $button.addClass('btn btn-primary row-action-container');
- $button.attr('title', button.name);
- $button.attr('onclick', button.handler + "('" + record.id + "')");
- $button.append($inner_button);
- $span.append($button);
+ if(button.type == 'simple-button') {
+ var $inner_button = $('');
+ $inner_button.addClass('row-action-icon');
+ $inner_button.addClass(button.css_class);
+ $inner_button.attr('title', button.name);
+ var $button = $('');
+ $button.addClass('btn btn-primary row-action-container');
+ $button.attr('title', button.name);
+ $button.attr('onclick', button.handler + "('" + record.id + "')");
+ $button.append($inner_button);
+ $span.append($button);
+ }
+ else if(button.type == 'dropdown'){
+ var $button = $('');
+ $button.addClass('btn btn-primary dropdown-toggle row-action-container');
+ $button.attr('title', button.name);
+ $button.attr('data-toggle', 'dropdown');
+ $button.attr('aria-haspopup', 'true');
+ $button.attr('aria-expanded', 'false');
+ var $inner_button = $('');
+ $inner_button.addClass('row-action-icon');
+ $inner_button.addClass(button.css_class);
+ $inner_button.attr(button.name);
+ $button.append($inner_button);
+ var $menu = $('
');
+ $menu.addClass('dropdown-menu');
+ for(var j=0;j < button.actions.length;j++){
+ var action = button.actions[j];
+ if(action.active && $.isFunction(action.active) && !action.active(record)){
+ continue;
+ }
+ var $li = $('');
+ var $action = $('');
+ if(action.href == undefined){
+ $action.attr('href', '#');
+ }
+ else if($.isFunction(action.href)){
+ $action.attr('href', action.href(record));
+ }
+
+ if(action.download && $.isFunction(action.download)){
+ $action.attr('download', action.download(record));
+ }
+
+ if(action.handler){
+ $action.attr('onclick', action.handler + "('" + record.id + "')");
+ }
+
+ $action.text(action.text);
+ $li.append($action);
+ $menu.append($li);
+ }
+ var $group = $('');
+ $group.addClass('btn-group');
+ $group.append($button);
+ $group.append($menu);
+ $span.append($group);
+ }
}
tr += '' + $span.html() + ' | ';
diff --git a/django_project/realtime/static/realtime/js/earthquake/shake.js b/django_project/realtime/static/realtime/js/earthquake/shake.js
index 2e3f9465..a82a6c80 100644
--- a/django_project/realtime/static/realtime/js/earthquake/shake.js
+++ b/django_project/realtime/static/realtime/js/earthquake/shake.js
@@ -464,17 +464,64 @@ function createActionRowWriter(button_templates, date_format) {
var $span = $('');
for (var i = 0; i < button_templates.length; i++) {
var button = button_templates[i];
- var $inner_button = $('');
- $inner_button.addClass('row-action-icon')
- $inner_button.addClass(button.css_class);
- $inner_button.attr('title', button.name);
- $inner_button.text(button.label);
- var $button = $('');
- $button.addClass('btn btn-primary row-action-container');
- $button.attr('title', button.name);
- $button.attr('onclick', button.handler + "('" + record.shake_id + "')");
- $button.append($inner_button);
- $span.append($button);
+ if(button.type == 'simple-button') {
+ var $inner_button = $('');
+ $inner_button.addClass('row-action-icon');
+ $inner_button.addClass(button.css_class);
+ $inner_button.attr('title', button.name);
+ var $button = $('');
+ $button.addClass('btn btn-primary row-action-container');
+ $button.attr('title', button.name);
+ $button.attr('onclick', button.handler + "('" + record.shake_id + "')");
+ $button.append($inner_button);
+ $span.append($button);
+ }
+ else if(button.type == 'dropdown'){
+ var $button = $('');
+ $button.addClass('btn btn-primary dropdown-toggle row-action-container');
+ $button.attr('title', button.name);
+ $button.attr('data-toggle', 'dropdown');
+ $button.attr('aria-haspopup', 'true');
+ $button.attr('aria-expanded', 'false');
+ var $inner_button = $('');
+ $inner_button.addClass('row-action-icon');
+ $inner_button.addClass(button.css_class);
+ $inner_button.attr(button.name);
+ $button.append($inner_button);
+ var $menu = $('');
+ $menu.addClass('dropdown-menu');
+ for(var j=0;j < button.actions.length;j++){
+ var action = button.actions[j];
+ if(action.active && $.isFunction(action.active) && !action.active(record)){
+ continue;
+ }
+ var $li = $('');
+ var $action = $('');
+ if(action.href == undefined){
+ $action.attr('href', '#');
+ }
+ else if($.isFunction(action.href)){
+ $action.attr('href', action.href(record));
+ }
+
+ if(action.download && $.isFunction(action.download)){
+ $action.attr('download', action.download(record));
+ }
+
+ if(action.handler){
+ $action.attr('onclick', action.handler + "('" + record.shake_id + "')");
+ }
+
+ $action.text(action.text);
+ $li.append($action);
+ $menu.append($li);
+ }
+ var $group = $('');
+ $group.addClass('btn-group');
+ $group.append($button);
+ $group.append($menu);
+ $span.append($group);
+ }
}
tr += '' + $span.html() + ' | ';
diff --git a/django_project/realtime/static/realtime/js/flood/flood.js b/django_project/realtime/static/realtime/js/flood/flood.js
index 67451239..b912adb9 100644
--- a/django_project/realtime/static/realtime/js/flood/flood.js
+++ b/django_project/realtime/static/realtime/js/flood/flood.js
@@ -166,7 +166,6 @@ function createShowFeaturesHandler(event_features_url){
// Deselect row in table
var $table = $("#realtime-table");
- console.log($table);
$table.find("tr.success").removeClass('success');
// Select row
$table.find("td:contains("+event_id+")").closest('tr').addClass('success');
@@ -252,17 +251,17 @@ function createShowImpactMapHandler(report_url) {
/**
* Closure to create handler for downloadReport
* @param {string} report_url A report url that contains shake_id placeholder
- * @return {function} Download the report based on shake_id
+ * @return {function} Download the impact map based on event_id
*/
-function createDownloadReportHandler(report_url) {
- var downloadReportHandler = function (shake_id) {
+function createDownloadImpactMapHandler(report_url) {
+ var downloadImpactMapHandler = function (event_id) {
var url = report_url;
- // replace magic number 000 with shake_id
- url = url.replace('000', shake_id);
+ // replace magic number 0000000000-6-rw with event_id
+ url = url.replace('0000000000-6-rw', event_id);
$.get(url, function (data) {
- if (data && data.report_pdf) {
- var pdf_url = data.report_pdf;
- SaveToDisk(pdf_url, data.shake_id+'-'+data.language+'.pdf');
+ if (data && data.impact_map) {
+ var pdf_url = data.impact_map;
+ SaveToDisk(pdf_url, data.event_id+'-'+data.language+'.pdf');
}
}).fail(function(e){
console.log(e);
@@ -271,7 +270,32 @@ function createDownloadReportHandler(report_url) {
}
});
};
- return downloadReportHandler;
+ return downloadImpactMapHandler;
+}
+
+/**
+ * Closure to create handler for downloadHazardLayer
+ * @return {function} Download the hazard layer based on event_id
+ */
+function createDownloadHazardLayerHandler() {
+ var downloadHazardLayerHandler = function (event_id) {
+ var event = undefined;
+ for(var i=0;i < event_json.length;i++){
+ event = event_json[i];
+ if(event_id == event.event_id){
+ break;
+ }
+ }
+
+ if(event == undefined){
+ alert("Event not found");
+ return;
+ }
+
+ var url = event.hazard_layer;
+ SaveToDisk(url, event.event_id + '-hazard.zip');
+ };
+ return downloadHazardLayerHandler;
}
/**
@@ -509,16 +533,64 @@ function createActionRowWriter(button_templates, date_format) {
var $span = $('');
for (var i = 0; i < button_templates.length; i++) {
var button = button_templates[i];
- var $inner_button = $('');
- $inner_button.addClass('row-action-icon')
- $inner_button.addClass(button.css_class);
- $inner_button.attr('title', button.name);
- var $button = $('');
- $button.addClass('btn btn-primary row-action-container');
- $button.attr('title', button.name);
- $button.attr('onclick', button.handler + "('" + record.event_id + "')");
- $button.append($inner_button);
- $span.append($button);
+ if(button.type == 'simple-button') {
+ var $inner_button = $('');
+ $inner_button.addClass('row-action-icon');
+ $inner_button.addClass(button.css_class);
+ $inner_button.attr('title', button.name);
+ var $button = $('');
+ $button.addClass('btn btn-primary row-action-container');
+ $button.attr('title', button.name);
+ $button.attr('onclick', button.handler + "('" + record.event_id + "')");
+ $button.append($inner_button);
+ $span.append($button);
+ }
+ else if(button.type == 'dropdown'){
+ var $button = $('');
+ $button.addClass('btn btn-primary dropdown-toggle row-action-container');
+ $button.attr('title', button.name);
+ $button.attr('data-toggle', 'dropdown');
+ $button.attr('aria-haspopup', 'true');
+ $button.attr('aria-expanded', 'false');
+ var $inner_button = $('');
+ $inner_button.addClass('row-action-icon');
+ $inner_button.addClass(button.css_class);
+ $inner_button.attr('title', button.name);
+ $button.append($inner_button);
+ var $menu = $('');
+ $menu.addClass('dropdown-menu');
+ for(var j=0;j < button.actions.length;j++){
+ var action = button.actions[j];
+ if(action.active && $.isFunction(action.active) && !action.active(record)){
+ continue;
+ }
+ var $li = $('');
+ var $action = $('');
+ if(action.href == undefined){
+ $action.attr('href', '#');
+ }
+ else if($.isFunction(action.href)){
+ $action.attr('href', action.href(record));
+ }
+
+ if(action.download && $.isFunction(action.download)){
+ $action.attr('download', action.download(record));
+ }
+
+ if(action.handler){
+ $action.attr('onclick', action.handler + "('" + record.event_id + "')");
+ }
+
+ $action.text(action.text);
+ $li.append($action);
+ $menu.append($li);
+ }
+ var $group = $('');
+ $group.addClass('btn-group');
+ $group.append($button);
+ $group.append($menu);
+ $span.append($group);
+ }
}
tr += '' + $span.html() + ' | ';
diff --git a/django_project/realtime/static/realtime/js/realtime.js b/django_project/realtime/static/realtime/js/realtime.js
index cfdfa7bd..db2d05f5 100644
--- a/django_project/realtime/static/realtime/js/realtime.js
+++ b/django_project/realtime/static/realtime/js/realtime.js
@@ -55,6 +55,7 @@ function browser_identity(){
*/
function SaveToDisk(fileURL, fileName) {
if (!window.ActiveXObject) {
+ // emulate button click on a element
var save = document.createElement('a');
save.href = fileURL;
if(!browser_identity().is_safari){
@@ -70,7 +71,7 @@ function SaveToDisk(fileURL, fileName) {
});
save.dispatchEvent(evt);
- (window.URL || window.webkitURL).revokeObjectURL(save.href);
+ // (window.URL || window.webkitURL).revokeObjectURL(save.href);
}
// for IE < 11
diff --git a/django_project/realtime/static/realtime/js/templates/ash/popup_content.jst b/django_project/realtime/static/realtime/js/templates/ash/popup_content.jst
index 074c0d5e..3c175390 100644
--- a/django_project/realtime/static/realtime/js/templates/ash/popup_content.jst
+++ b/django_project/realtime/static/realtime/js/templates/ash/popup_content.jst
@@ -42,13 +42,37 @@
onclick="showReportHandler('<%= id %>')">
-
+
+
+
+
diff --git a/django_project/realtime/static/realtime/js/templates/earthquake/popup_content.jst b/django_project/realtime/static/realtime/js/templates/earthquake/popup_content.jst
index b0717bc5..2c8230a7 100644
--- a/django_project/realtime/static/realtime/js/templates/earthquake/popup_content.jst
+++ b/django_project/realtime/static/realtime/js/templates/earthquake/popup_content.jst
@@ -30,19 +30,37 @@
onclick="showReportHandler('<%= shake_id %>')">
-
-
+
+
+
+
diff --git a/django_project/realtime/tasks/flood.py b/django_project/realtime/tasks/flood.py
index 0e9623f6..e5df09f6 100644
--- a/django_project/realtime/tasks/flood.py
+++ b/django_project/realtime/tasks/flood.py
@@ -7,6 +7,8 @@
import tempfile
from zipfile import ZipFile
+from django.contrib.gis.gdal.error import OGRIndexError
+
from realtime.app_settings import OSM_LEVEL_7_NAME, OSM_LEVEL_8_NAME
from core.celery_app import app
from django.conf import settings
@@ -70,12 +72,17 @@ def process_hazard_layer(flood):
rw = BoundaryAlias.objects.get(alias=OSM_LEVEL_8_NAME)
for feat in layer:
- pkey = feat.get('pkey')
- level_name = feat.get('level_name')
- # flooded = feat.get('flooded')
- # count = feat.get('count')
- parent_name = feat.get('parent_nam')
- state = feat.get('state')
+ if not flood.data_source or flood.data_source == 'petajakarta':
+ upstream_id = feat.get('pkey')
+ level_name = feat.get('level_name')
+ parent_name = feat.get('parent_nam')
+ state = feat.get('state')
+ elif flood.data_source == 'petabencana':
+ upstream_id = feat.get('area_id')
+ level_name = feat.get('area_name')
+ parent_name = feat.get('parent_nam')
+ state = feat.get('state')
+
geometry = feat.geom
geos_geometry = GEOSGeometry(geometry.geojson)
@@ -91,7 +98,7 @@ def process_hazard_layer(flood):
boundary_alias=kelurahan)
except Boundary.DoesNotExist:
boundary_kelurahan = Boundary.objects.create(
- upstream_id=pkey,
+ upstream_id=upstream_id,
geometry=geos_geometry,
name=parent_name,
boundary_alias=kelurahan)
@@ -99,13 +106,13 @@ def process_hazard_layer(flood):
try:
boundary_rw = Boundary.objects.get(
- upstream_id=pkey, boundary_alias=rw)
+ upstream_id=upstream_id, boundary_alias=rw)
boundary_rw.geometry = geos_geometry
boundary_rw.name = level_name
boundary_rw.parent = boundary_kelurahan
except Boundary.DoesNotExist:
boundary_rw = Boundary.objects.create(
- upstream_id=pkey,
+ upstream_id=upstream_id,
geometry=geos_geometry,
name=level_name,
parent=boundary_kelurahan,
@@ -168,7 +175,10 @@ def process_impact_layer(flood):
for feat in layer:
level_7_name = feat.get('NAMA_KELUR').strip()
- hazard_class = feat.get('affected')
+ try:
+ hazard_class = feat.get('affected')
+ except OGRIndexError:
+ hazard_class = feat.get('safe_ag')
population_affected = feat.get('Pop_Total')
geometry = feat.geom
geos_geometry = GEOSGeometry(geometry.geojson)
diff --git a/django_project/realtime/templates/realtime/ash/index.html b/django_project/realtime/templates/realtime/ash/index.html
index 00e338e3..33eefa26 100644
--- a/django_project/realtime/templates/realtime/ash/index.html
+++ b/django_project/realtime/templates/realtime/ash/index.html
@@ -168,16 +168,42 @@ {% trans "Ash Fall" %}
{# Use magic number 000 for placeholders #}
var report_url = '{% url "realtime:ash_report_detail" volcano_name='VOLCANOTEMPLATENAME' event_time='1234567890123456789' language=language.selected_language.id %}';
var showReportHandler = createShowReportHandler(report_url);
+ var downloadReportHandler = createDownloadReportHandler(report_url);
var button_templates = [
{
- name: 'Zoom',
+ type: 'simple-button',
+ name: '{% trans "Zoom" %}',
css_class: 'glyphicon glyphicon-search',
handler: 'showEventHandler'
},
{
- name: 'Report',
+ type: 'simple-button',
+ name: '{% trans "Report" %}',
css_class: 'glyphicon glyphicon-file',
handler: 'showReportHandler'
+ },
+ {
+ type: 'dropdown',
+ name: '{% trans "Download" %}',
+ css_class: 'glyphicon glyphicon-download',
+ actions: [
+ {
+ active: function(event){return event.hazard_file != undefined;},
+ text: '{% trans "Hazard File" %}',
+ href: function(event){return event.hazard_file;},
+ download: function(event){return event.event_id_formatted+'-hazard.tif';}
+ },
+ {
+ active: function(event){return event.impact_files != undefined;},
+ text: '{% trans "Impact Files" %}',
+ href: function(event){return event.impact_files;},
+ download: function(event){return event.event_id_formatted+'-impact.zip';}
+ },
+ {
+ text: '{% trans "Report" %}',
+ handler: 'downloadReportHandler'
+ }
+ ]
}
];
@@ -199,6 +225,11 @@ {% trans "Ash Fall" %}
dynaTable.paginationPerPage.set(10);
dynaTable.sorts.add('event_time', -1);
dynaTable.process();
+
+ if(jsonTableContents.length > 0){
+ var event_id = jsonTableContents[0].id
+ showEventHandler(event_id);
+ }
}
function onEachFeature(feature, layer) {
@@ -237,7 +268,6 @@ {% trans "Ash Fall" %}
$.get(get_events_url, function (data) {
event_json = data;
getAshEventsJson(data);
- mapFitAll(map, markers);
});
});
diff --git a/django_project/realtime/templates/realtime/earthquake/index.html b/django_project/realtime/templates/realtime/earthquake/index.html
index 191c32c4..800c7657 100644
--- a/django_project/realtime/templates/realtime/earthquake/index.html
+++ b/django_project/realtime/templates/realtime/earthquake/index.html
@@ -299,8 +299,7 @@ InaSAFE
// create dynatable
var jsonTableContents = [];
- var showEventHandler = createShowEventHandler(map, markers,
- map_events);
+ var showEventHandler = createShowEventHandler(map, markers, map_events);
{# Use magic number 000 for placeholder#}
var report_url = '{% url "realtime:earthquake_report_detail" shake_id='000' language=language.selected_language.id %}';
var report_download_url = '{% url "realtime_report:report_pdf" shake_id='000' language=language.selected_language.id language2=language.selected_language.id %}';
@@ -310,25 +309,38 @@ InaSAFE
var downloadGridHandler = createDownloadGridHandler(grid_url);
var button_templates = [
{
+ type: 'simple-button',
name: '{% trans "Zoom" %}',
css_class: 'glyphicon glyphicon-search',
handler: 'showEventHandler'
},
{
+ type: 'simple-button',
name: '{% trans "Report" %}',
css_class: 'glyphicon glyphicon-file',
handler: 'showReportHandler'
},
{
+ type: 'dropdown',
name: '{% trans "Download" %}',
css_class: 'glyphicon glyphicon-download',
- handler: 'downloadReportHandler'
- },
- {
- name: '{% trans "Grid" %}',
- css_class: 'glyphicon glyphicon-download',
- handler: 'downloadGridHandler',
- label: 'XML'
+ actions: [
+ {
+ text: '{% trans "Report" %}',
+ handler: 'downloadReportHandler'
+ },
+ {
+ active: function(event){return event.shake_grid != undefined;},
+ text: '{% trans "Grid XML" %}',
+ handler: 'downloadGridHandler'
+ },
+ {
+ active: function(event){return event.mmi_output != undefined;},
+ text: '{% trans "MMI output" %}',
+ href: function(event){return event.mmi_output;},
+ download: function(event){return event.shake_id+'-mmi.zip'}
+ }
+ ]
}
];
@@ -351,6 +363,11 @@ InaSAFE
dynaTable.paginationPerPage.set(20);
dynaTable.sorts.add('time', -1);
dynaTable.process();
+
+ if(jsonTableContents.length > 0){
+ var shake_id = jsonTableContents[0].shake_id;
+ showEventHandler(shake_id);
+ }
}
function onEachFeature(feature, layer) {
@@ -417,7 +434,6 @@ InaSAFE
event_json = data;
getEarthquakeEventsJson(data);
modifyMapDescriptions(".map-title");
- mapFitAll(map, markers);
});
// add content filter handler
diff --git a/django_project/realtime/templates/realtime/flood/index.html b/django_project/realtime/templates/realtime/flood/index.html
index fd8ca2ae..80c686ad 100644
--- a/django_project/realtime/templates/realtime/flood/index.html
+++ b/django_project/realtime/templates/realtime/flood/index.html
@@ -237,24 +237,44 @@ {% trans "Flood" %}
var report_url = '{% url "realtime:flood_report_detail" event_id='0000000000-6-rw' language=language.selected_language.id %}';
var showReportHandler = createShowReportHandler(report_url);
var showImpactMapHandler = createShowImpactMapHandler(report_url);
-{# var downloadReportHandler = createDownloadReportHandler(report_url);#}
+ var downloadImpactMapHandler = createDownloadImpactMapHandler(report_url);
var button_templates = [
{
- name: 'Show',
+ type: 'simple-button',
+ name: '{% trans "Show" %}',
css_class: 'glyphicon glyphicon-search',
handler: 'showFeaturesHandler'
},
{
- name: 'Impact Map',
- css_class: 'glyphicon glyphicon-globe',
+ type: 'simple-button',
+ name: '{% trans "Report" %}',
+ css_class: 'glyphicon glyphicon-file',
handler: 'showImpactMapHandler'
},
-{# {#}
-{# name: 'Download',#}
-{# css_class: 'glyphicon glyphicon-download',#}
-{# handler: 'downloadReportHandler'#}
-{# }#}
+ {
+ type: 'dropdown',
+ name: '{% trans "Download" %}',
+ css_class: 'glyphicon glyphicon-download',
+ actions: [
+ {
+ active: function(event){return event.hazard_layer !== undefined;},
+ text: '{% trans "Hazard Layer" %}',
+ href: function(event){return event.hazard_layer;},
+ download: function(event){return event.event_id+'-hazard.zip';}
+ },
+ {
+ active: function(event){return event.impact_layer !== undefined;},
+ text: '{% trans "Impact Layer" %}',
+ href: function(event){return event.impact_layer;},
+ download: function(event){return event.event_id+'-impact.zip';}
+ },
+ {
+ text: '{% trans "Impact Map" %}',
+ handler: 'downloadImpactMapHandler'
+ }
+ ]
+ }
];
$(document).ready(function(){
diff --git a/django_project/realtime/views/ash.py b/django_project/realtime/views/ash.py
index 43b426fb..82af22ab 100644
--- a/django_project/realtime/views/ash.py
+++ b/django_project/realtime/views/ash.py
@@ -165,7 +165,7 @@ class AshDetail(mixins.RetrieveModelMixin, mixins.UpdateModelMixin,
queryset = Ash.objects.all()
serializer_class = AshSerializer
lookup_field = 'id'
- parser_classes = [JSONParser, FormParser]
+ parser_classes = [JSONParser, FormParser, MultiPartParser]
permission_classes = (DjangoModelPermissionsOrAnonReadOnly, )
def get(self, request, volcano_name=None, event_time=None):
@@ -192,12 +192,18 @@ def get(self, request, volcano_name=None, event_time=None):
serializer = self.get_serializer(instance)
return Response(serializer.data)
- def put(self, request, *args, **kwargs):
+ def put(self, request, volcano_name=None, event_time=None,
+ *args, **kwargs):
try:
- event_id = request.data['id']
- if event_id:
- event = Ash.objects.get(id=event_id)
- event.hazard_file.delete()
+ if volcano_name and event_time:
+ instance = Ash.objects.get(
+ volcano__volcano_name__iexact=volcano_name,
+ event_time=parse(event_time))
+ self.kwargs.update(id=instance.id)
+ if 'hazard_file' in request.FILES and instance.hazard_file:
+ instance.hazard_file.delete()
+ if 'impact_files' in request.FILES and instance.impact_files:
+ instance.impact_files.delete()
retval = self.update(request, partial=True, *args, **kwargs)
return retval
else:
diff --git a/django_project/realtime/views/earthquake.py b/django_project/realtime/views/earthquake.py
index 2c37c465..1034eaa5 100644
--- a/django_project/realtime/views/earthquake.py
+++ b/django_project/realtime/views/earthquake.py
@@ -182,21 +182,13 @@ def put(self, request, *args, **kwargs):
data = request.data
shake_id = kwargs.get('shake_id') or data.get('shake_id')
instance = Earthquake.objects.get(shake_id=shake_id)
- if instance.shake_grid:
+ if 'shake_grid' in request.FILES and instance.shake_grid:
instance.shake_grid.delete()
- if 'shake_grid' in request.data:
- # posting shake grid means only updating its shake_grid
- # properties
- request.data['shake_id'] = shake_id
- request.data['location'] = instance.location
- request.data['location_description'] = \
- instance.location_description
- request.data['time'] = instance.time
- request.data['magnitude'] = instance.magnitude
- request.data['depth'] = instance.depth
+ if 'mmi_output' in request.FILES and instance.mmi_output:
+ instance.mmi_output.delete()
except Earthquake.DoesNotExist:
pass
- retval = self.update(request, *args, **kwargs)
+ retval = self.update(request, partial=True, *args, **kwargs)
track_rest_push(request)
return retval
diff --git a/django_project/realtime/views/flood.py b/django_project/realtime/views/flood.py
index 0bf1405b..0ae0903e 100644
--- a/django_project/realtime/views/flood.py
+++ b/django_project/realtime/views/flood.py
@@ -140,8 +140,10 @@ def put(self, request, *args, **kwargs):
event_id = request.data['event_id']
if event_id:
event = Flood.objects.get(event_id=event_id)
- event.hazard_layer.delete()
- event.impact_layer.delete()
+ if 'hazard_layer' in request.FILES and event.hazard_layer:
+ event.hazard_layer.delete()
+ if 'impact_layer' in request.FILES and event.impact_layer:
+ event.impact_layer.delete()
retval = self.update(request, partial=True, *args, **kwargs)
return retval
else: