(function (angular) {
'use strict';
/**
* @memberof spApp
* @ngdoc controller
* @name AreaReportCtrl
* @description
* Generate and display an area report
*/
angular.module('area-report-ctrl', ['map-service', 'biocache-service', 'lists-service', 'layers-service'])
.controller('AreaReportCtrl', ['$scope', 'MapService', '$timeout', 'LayoutService', '$uibModalInstance',
'BiocacheService', 'data', '$http', 'ListsService', 'LayersService', 'EventService', '$q',
function ($scope, MapService, $timeout, LayoutService, $uibModalInstance, BiocacheService, data, $http,
ListsService, LayersService, EventService, $q) {
LayoutService.addToModeless($scope);
$scope._httpDescription = function (method, httpconfig) {
if (httpconfig === undefined) {
httpconfig = {};
}
httpconfig.service = 'AreaReportCtrl';
httpconfig.method = method;
httpconfig.ignoreErrors = true;
return httpconfig;
};
$scope.area = data;
$scope.endemic = data.endemic;
$scope.openExpertDistribution = '';
$scope.openJournalMapDocuments = '';
$scope.exportUrl = null;
$scope.journalMapDocumentCount = function () {
if ($scope.area.wkt !== undefined && $scope.area.wkt.length > 0) {
return $http.get(LayersService.url() + "/journalMap/search?wkt=" + $scope.area.wkt, $scope._httpDescription('journalmapCount')).then(function (response) {
return $scope.setJournalMapCount(response.data)
});
} else if (!($scope.area.pid.indexOf('~'))) {
return $http.get(LayersService.url() + "/journalMap/search?pid=" + $scope.area.pid, $scope._httpDescription('journalmapCount')).then(function (response) {
return $scope.setJournalMapCount(response.data)
});
} else {
var wkt = $scope.bboxToWkt($scope.area.bbox)
return $http.get(LayersService.url() + "/journalMap/search?wkt=" + wkt, $scope._httpDescription('journalmapCount')).then(function (response) {
return $scope.setJournalMapCount(response.data)
});
}
};
$scope.distributions = [];
$scope.setDistributionCount = function (data) {
for (var i in data) {
if (data.hasOwnProperty(i)) {
$scope.distributions.push(data[i]);
}
}
for (var k in $scope.items) {
if ($scope.items.hasOwnProperty(k)) {
if ($i18n(356, "Expert distributions") === $scope.items[k].name) {
$scope.items[k].value = data.length
}
}
}
return $q.when(true)
};
$scope.journalMap = [];
$scope.setJournalMapCount = function (data) {
for (var i in data.article) {
if (data.article.hasOwnProperty(i)) {
$scope.journalMap.push(data.article[i]);
}
}
for (var k in $scope.items) {
if ($scope.items.hasOwnProperty(k)) {
if ($i18n(357, "JournalMap articles") === $scope.items[k].name) {
$scope.items[k].value = data.count
}
}
}
return $q.when(true)
};
$scope.distributionCounts = function () {
if ($scope.area.wkt !== undefined && $scope.area.wkt.length > 0) {
return $http.get(LayersService.url() + "/distributions?wkt=" + $scope.area.wkt, $scope._httpDescription('distributionCounts')).then(function (response) {
return $scope.setDistributionCount(response.data)
});
} else if (($scope.area.pid + '').indexOf('~') < 0) {
return $http.get(LayersService.url() + "/distributions?pid=" + $scope.area.pid, $scope._httpDescription('distributionCounts')).then(function (response) {
return $scope.setDistributionCount(response.data)
});
} else {
var wkt = $scope.bboxToWkt($scope.area.bbox)
return $http.get(LayersService.url() + "/distributions?wkt=" + encodeURIComponent(wkt), $scope._httpDescription('distributionCounts')).then(function (response) {
return $scope.setDistributionCount(response.data)
});
}
};
$scope.checklists = [];
$scope.setChecklistCount = function (data) {
for (var i in data) {
if (data.hasOwnProperty(i)) {
$scope.checklists.push(data[i]);
}
}
var areas = {};
for (var k in data) {
if (data.hasOwnProperty(k)) {
areas[data[k].area_name] = data[k]
}
}
var areaCount = 0;
for (k in areas) {
areaCount++
}
for (k in $scope.items) {
if ($scope.items.hasOwnProperty(k)) {
if ($i18n(358, "Checklist species distributions") === $scope.items[k].name) {
$scope.items[k].value = data.length
}
if ($i18n(359, "Checklist areas") === $scope.items[k].name) {
$scope.items[k].value = areaCount
}
}
}
return $q.when(true)
};
$scope.checklistCounts = function () {
if ($scope.area.wkt !== undefined && $scope.area.wkt.length > 0) {
return $http.get(LayersService.url() + "/checklists?wkt=" + $scope.area.wkt, $scope._httpDescription('checklistCounts')).then(function (response) {
return $scope.setChecklistCount(response.data)
});
} else if (($scope.area.pid + '').indexOf('~') < 0) {
return $http.get(LayersService.url() + "/checklists?pid=" + $scope.area.pid, $scope._httpDescription('checklistCounts')).then(function (response) {
return $scope.setChecklistCount(response.data)
});
} else {
var wkt = $scope.bboxToWkt($scope.area.bbox)
return $http.get(LayersService.url() + "/checklists?wkt=" + encodeURIComponent(wkt), $scope._httpDescription('checklistCounts')).then(function (response) {
return $scope.setChecklistCount(response.data)
});
}
};
$scope.bboxToWkt = function (bbox) {
return 'POLYGON((' + bbox[0][1] + ' ' + bbox[0][0] + ',' + bbox[1][1] + ' ' + bbox[0][0] + ',' + bbox[1][1] + ' ' + bbox[1][0] + ',' + bbox[0][1] + ' ' + bbox[1][0] + ',' + bbox[0][1] + ' ' + bbox[0][0] + '))'
}
$scope.gazPoints = [];
$scope.setGazCount = function (data) {
$scope.gazPoints = data;
for (var k in $scope.items) {
if ($scope.items.hasOwnProperty(k)) {
if ($i18n(360, "Gazetteer Points") === $scope.items[k].name) {
$scope.items[k].value = data.length
}
}
}
return $q.when(true)
};
$scope.gazPointCounts = function () {
if ($scope.area.wkt !== undefined && $scope.area.wkt.length > 0) {
return $http.get(LayersService.url() + "/objects/inarea/" + LayersService.gazField() + "?wkt=" + $scope.area.wkt + "&limit=9999999", $scope._httpDescription('gazetteerCounts')).then(function (response) {
return $scope.setGazCount(response.data)
});
} else if (($scope.area.pid + '').indexOf('~') < 0) {
return $http.get(LayersService.url() + "/objects/inarea/" + LayersService.gazField() + "?pid=" + $scope.area.pid + "&limit=9999999", $scope._httpDescription('gazetteerCounts')).then(function (response) {
return $scope.setGazCount(response.data)
});
} else {
var wkt = $scope.bboxToWkt($scope.area.bbox)
return $http.get(LayersService.url() + "/objects/inarea/" + LayersService.gazField() + "?wkt=" + encodeURIComponent(wkt) + "&limit=9999999", $scope._httpDescription('gazetteerCounts')).then(function (response) {
return $scope.setGazCount(response.data)
});
}
return $q.when(true)
};
$scope.poi = [];
$scope.setPoi = function (data) {
$scope.poi = data;
for (var k in $scope.items) {
if ($scope.items.hasOwnProperty(k)) {
if ($i18n(361, "Points of interest") === $scope.items[k].name) {
$scope.items[k].value = data.length
}
}
}
return $q.when(true)
};
$scope.biocollectCounts = function (idx) {
if ($SH.biocollectReport && $SH.biocollectReport.length > idx) {
var bbox = $scope.area.bbox
var shape = JSON.stringify({
type: 'Polygon',
coordinates: [[[bbox[0], bbox[1]], [bbox[2], bbox[1]], [bbox[2], bbox[3]], [bbox[0], bbox[3]], [bbox[0], bbox[1]]]]
})
var geoSearchJSON = encodeURIComponent(shape)
var geoSearchEncoded = encodeURIComponent(LZString.compressToBase64(shape))
var name = $SH.biocollectReport[idx].name
var countUrl = $SH.biocollectReport[idx].count.replace('_geoSearchJSON_', geoSearchJSON).replace('_geoSearchEncoded', geoSearchEncoded)
var linkUrl = $SH.biocollectReport[idx].link.replace('_geoSearchJSON_', geoSearchJSON).replace('_geoSearchEncoded', geoSearchEncoded)
return $http.get(countUrl, $scope._httpDescription('biocollectCounts')).then(function (response) {
return {count: response.data.hits.total, link: linkUrl, linkName: 'list', name: name}
});
} else {
return $q.when({})
}
};
$scope.pointOfInterestCounts = function () {
if ($scope.area.wkt !== undefined && $scope.area.wkt.length > 0) {
return $http.get(LayersService.url() + "/intersect/poi/wkt?wkt=" + $scope.area.wkt + "&limit=9999999", $scope._httpDescription('pointsOfInterestCount')).then(function (response) {
return $scope.setPoi(response.data)
});
} else if (($scope.area.pid + '').indexOf('~') < 0) {
return $http.get(LayersService.url() + "/intersect/poi/wkt?pid=" + $scope.area.pid + "&limit=9999999", $scope._httpDescription('pointsOfInterestCount')).then(function (response) {
return $scope.setPoi(response.data)
});
} else {
var wkt = $scope.bboxToWkt($scope.area.bbox)
return $http.get(LayersService.url() + "/intersect/poi/wkt?wkt=" + encodeURIComponent(wkt) + "&limit=9999999", $scope._httpDescription('pointsOfInterestCount')).then(function (response) {
return $scope.setPoi(response.data)
});
}
};
$scope.items = [];
$scope.init = function (areaQ) {
BiocacheService.registerQuery(areaQ).then(function (response) {
if (response == null) {
return
}
areaQ.qid = response.qid;
$scope.items = [
{
name: $i18n(348, "Area (sq km)"),
link: $i18n(362, "https://www.ala.org.au/spatial-portal-help/note-area-sq-km/"),
linkName: $i18n(363, "Info"),
value: $scope.area.area_km.toFixed(2)
},
{
name: $i18n(364, "Number of species"),
query: {q: areaQ.q, bs: areaQ.bs, ws: areaQ.ws, wkt: areaQ.wkt, qid: areaQ.qid},
map: false
},
{
name: $i18n(365, "Number of species - spatially valid only"),
query: {q: areaQ.q, bs: areaQ.bs, ws: areaQ.ws, wkt: areaQ.wkt, qid: areaQ.qid},
map: false,
extraQ: ["geospatial_kosher:true"]
},
{
name: $i18n(366, "Number of endemic species"),
endemic: true,
query: {q: areaQ.q, bs: areaQ.bs, ws: areaQ.ws, wkt: areaQ.wkt, qid: areaQ.qid},
map: false
},
{
name: $i18n(429, "Number of endemic species - spatially valid only"),
endemic: true,
query: {q: areaQ.q, bs: areaQ.bs, ws: areaQ.ws, wkt: areaQ.wkt, qid: areaQ.qid},
map: false,
extraQ: ["geospatial_kosher:true"]
}];
// TODO: move this into config and retrieve from $SH
$.each([
{
name: $i18n(282, "Occurrences"),
query: {q: areaQ.q, bs: areaQ.bs, ws: areaQ.ws, wkt: areaQ.wkt, qid: areaQ.qid},
occurrences: true
},
{
name: $i18n(368, "Occurrences - spatially valid only"),
query: {q: areaQ.q, bs: areaQ.bs, ws: areaQ.ws, wkt: areaQ.wkt, qid: areaQ.qid},
occurrences: true,
extraQ: ["geospatial_kosher:true"]
},
{
name: $i18n(356, "Expert distributions"),
list: $scope.distributions,
value: ''
},
{
name: $i18n(359, "Checklist areas"),
value: ''
},
{
name: $i18n(358, "Checklist species distributions"),
list: $scope.checklists,
value: ''
},
{
name: $i18n(357, "JournalMap articles"),
list: $scope.journalMap,
link: $SH.journalMapUrl,
linkName: $i18n(369, "JournalMap"),
value: '',
ignore: $SH.journalMapUrl === ''
},
{
name: $i18n(360, "Gazetteer Points"),
mapGaz: true,
value: ''
},
{
name: $i18n(361, "Points of interest"),
value: ''
},
{
name: $i18n(370, "Invasive Species"),
query: {
q: areaQ.q.concat([$SH.invasiveQ]),
bs: areaQ.bs,
ws: areaQ.ws,
wkt: areaQ.wkt,
qid: areaQ.qid
},
extraQ: [$SH.invasiveQ],
ignore: $SH.listsUrl === '' || $SH.invasiveQ === ''
},
{
name: $i18n(371, "Threatened Species"),
query: {
q: areaQ.q.concat([$SH.threatenedQ]),
bs: areaQ.bs,
ws: areaQ.ws,
wkt: areaQ.wkt
},
extraQ: [$SH.threatenedQ],
ignore: $SH.listsUrl === '' || $SH.threatenedQ === ''
},
{
name: $i18n(372, "Migratory species - EPBC"),
query: {q: areaQ.q, bs: areaQ.bs, ws: areaQ.ws, wkt: areaQ.wkt, qid: areaQ.qid},
link: ListsService.url() + '/speciesListItem/list/' + $SH.migratoryDR,
linkName: $i18n(373, "Full list"),
extraQ: ["species_list_uid:" + $SH.migratoryDR],
ignore: $SH.listsUrl === '' || $SH.migratoryDR === ''
},
{
name: $i18n(374, "Australian iconic species"),
query: {q: areaQ.q, bs: areaQ.bs, ws: areaQ.ws, wkt: areaQ.wkt, qid: areaQ.qid},
link: ListsService.url() + '/speciesListItem/list/' + $SH.iconicSpeciesDR,
linkName: $i18n(373, "Full list"),
extraQ: ["species_list_uid:" + $SH.iconicSpeciesDR],
ignore: $SH.listsUrl === '' || $SH.iconicSpeciesDR === ''
}], function (i, v) {
if (v.ignore === undefined || !v.ignore) {
$scope.items.push(v)
}
});
$.each(['Algae', 'Amphibians', 'Angiosperms', 'Animals', 'Arthropods', 'Bacteria', 'Birds',
'Bryophytes', 'Chromista', 'Crustaceans', 'Dicots', 'FernsAndAllies', 'Fish', 'Fungi',
'Gymnosperms', 'Insects', 'Mammals', 'Molluscs', 'Monocots', 'Plants', 'Protozoa', 'Reptiles'], function (i, v) {
$scope.items.push({
name: v,
query: {q: areaQ.q, bs: areaQ.bs, ws: areaQ.ws, wkt: areaQ.wkt, qid: areaQ.qid},
extraQ: ["species_group:" + v]
})
});
if ($SH.biocollectReport) {
$.each($SH.biocollectReport, function (i, v) {
$scope.biocollectCounts(i).then(function (data) {
$scope.items.push(data)
})
})
}
$timeout(function () {
$scope.checklistCounts().then(function () {
$scope.distributionCounts().then(function () {
$scope.journalMapDocumentCount().then(function () {
$scope.gazPointCounts().then(function () {
$scope.pointOfInterestCounts()
})
})
})
})
}, 0);
$scope.countNextItem($scope.items, 0);
});
};
$scope.countNextItem = function(items, index) {
if (index < items.length) {
if (items[index].query !== undefined) {
items[index].value = '';
if (items[index].occurrences !== undefined && items[index].occurrences) {
$scope.count(items[index], BiocacheService.count(items[index].query, items[index].extraQ)).then(function (count) {
$scope.countNextItem(items, index + 1)
})
} else if (items[index].name.indexOf('endemic') >= 0) {
$scope.count(items[index], BiocacheService.speciesCountEndemic(items[index].query, items[index].extraQ))
// endemic counts are slow, do not wait
$scope.countNextItem(items, index + 1)
} else {
$scope.count(items[index], BiocacheService.speciesCount(items[index].query, items[index].extraQ)).then(function (count) {
$scope.countNextItem(items, index + 1)
})
}
} else {
$scope.countNextItem(items, index + 1)
}
} else {
$scope.makeCSV()
}
}
$scope.count = function (item, promise) {
return promise.then(function (data) {
item.value = data
})
};
$scope.listCsv = function (data, name) {
var csv = '';
var header = [];
// use first record to determine the header
for (var j in data[0]) {
var content = data[0][j];
if (('' + content).indexOf("[object") < 0) {
header.push(j);
var value = '"' + j.replace('"', "'") + '"';
if (csv.length > 0) csv += ',';
csv += value;
}
}
csv += '\n'
for (var i in data) {
var rowLength = 0;
for (var j in header) {
var value = data[i][header[j]];
if (value === undefined) value = '';
var value = '"' + ('' + value).replace('"', "'") + '"';
if (rowLength > 0) csv += ',';
rowLength++;
csv += value;
}
csv += '\n'
}
LayoutService.openModal('csv', {
title: name,
csv: csv,
columnOrder: [],
info: name + ' csv',
filename: name.replace(' ', '') + '.csv',
display: {size: 'full'}
}, true)
};
$scope.list = function (item) {
BiocacheService.speciesList(item.query, item.extraQ).then(function (data) {
LayoutService.openModal('csv', {
title: item.name,
csv: data,
columnOrder: [],
info: item.name + ' csv',
filename: item.name.replace(' ', '') + '.csv',
display: {size: 'full'}
}, true)
})
};
$scope.map = function (event, item) {
event.currentTarget.classList.add('disabled');
if (item.extraQ === undefined) item.extraQ = [];
var q = {q: areaQ.q, ws: areaQ.ws, bs: areaQ.bs, wkt: areaQ.wkt, name: item.name};
EventService.facetNewLayer(areaQ, item.extraQ)
};
$scope.sample = function (item) {
if (item.extraQ === undefined) item.extraQ = [];
var query = {q: areaQ.q.concat(item.extraQ), ws: areaQ.ws, bs: areaQ.bs, wkt: areaQ.wkt};
var area = {area: [$scope.area]};
var data = {
overrideValues: {
ToolExportSampleService: {
input: {
species: {constraints: {'default': query, disable: true}},
area: {constraints: {'default': area, disable: true}}
}
}
},
processName: "ToolExportSampleService"
};
LayoutService.clear();
LayoutService.openModal('tool', data)
};
$scope.makeCSV = function () {
var counting = false;
for (var k in $scope.items) {
if ($scope.items.hasOwnProperty(k)) {
if ($scope.items[k].value === '') {
counting = true
}
}
}
var csv = '';
for (k in $scope.items) {
if ($scope.items.hasOwnProperty(k)) {
csv = csv + $scope.items[k].name + ',' + $scope.items[k].value + '\n'
}
}
var blob = new Blob([csv], {type: 'text/plain'});
$scope.exportUrl = (window.URL || window.webkitURL).createObjectURL(blob);
if (counting) {
$timeout(function () {
$scope.makeCSV()
}, 2000)
}
};
$scope.makeModeless = function () {
$('.modal').addClass('modeless');
$('.modal-dialog').draggable({
handle: ".modal-header"
});
$('.modal-content').resizable({
minHeight: 180,
minWidth: 350
});
$('.modal-content').on("resize", function () {
$('.modal-body').height($('.modal-dialog').height() - $('.modal-header').outerHeight() - $('.modal-footer').outerHeight() - ($('.modal-body').outerHeight() - $('.modal-body').height()))
}).trigger('resize');
};
// build area query
var areaQ = jQuery.extend({}, $scope.area);
areaQ.bs = BiocacheService.newQuery().bs;
areaQ.ws = BiocacheService.newQuery().ws;
if (areaQ.q === undefined || areaQ.q.length === 0) {
areaQ.q = ["*:*"];
if (areaQ.wkt === undefined && areaQ.pid !== undefined) {
areaQ.wkt = areaQ.pid
}
} else {
areaQ.wkt = undefined;
}
$scope.init(areaQ);
$timeout($scope.makeModeless, 0);
}])
}(angular));