Branching to roll Release Candidate v5 for 0.1-incubating
git-svn-id: https://svn.apache.org/repos/asf/incubator/climate/branches/0.1-incubating@1507020 13f79535-47bb-0310-9956-ffa450edef68
Former-commit-id: 418ced716599893d4da7a6ccc3a3fe9691141743
diff --git a/CHANGES.txt.REMOVED.git-id b/CHANGES.txt.REMOVED.git-id
index 2b8d037..4ca45d4 100644
--- a/CHANGES.txt.REMOVED.git-id
+++ b/CHANGES.txt.REMOVED.git-id
@@ -1 +1 @@
-e5a124f85553ed7bf4d0806f438889e9d0bdc589
\ No newline at end of file
+533b25ac6cfed3b2e89d2435b7618dc305f4acea
\ No newline at end of file
diff --git a/LICENSE.txt.REMOVED.git-id b/LICENSE.txt.REMOVED.git-id
index 862a03c..76c39f4 100644
--- a/LICENSE.txt.REMOVED.git-id
+++ b/LICENSE.txt.REMOVED.git-id
@@ -1 +1 @@
-d645695673349e3947e8e5ae42332d0ac3164cd7
\ No newline at end of file
+4755709d3ec39bfe811dd2ccd26c11470e850d0f
\ No newline at end of file
diff --git a/easy-rcmet/install.sh b/easy-rcmet/install.sh
index 26b3785..31c22f6 100755
--- a/easy-rcmet/install.sh
+++ b/easy-rcmet/install.sh
@@ -174,9 +174,9 @@
http://www.virtualenv.org/en/latest/
http://virtualenvwrapper.readthedocs.org/en/latest/
-Additonally, you should set your PYTHON_PATH environment variable to point to the
+Additonally, you should set your PYTHONPATH environment variable to point to the
RCMET code base that was downloaded into ./src/rcmes. For example:
- export PYTHON_PATH=/path/to/this/script/src/rcmes:$PYTHON_PATH
+ export PYTHONPATH=/path/to/this/script/src/rcmes:$PYTHONPATH
OUTRO
diff --git a/rcmet/LICENSE.txt.REMOVED.git-id b/rcmet/LICENSE.txt.REMOVED.git-id
index 862a03c..ca77b59 100644
--- a/rcmet/LICENSE.txt.REMOVED.git-id
+++ b/rcmet/LICENSE.txt.REMOVED.git-id
@@ -1 +1 @@
-d645695673349e3947e8e5ae42332d0ac3164cd7
\ No newline at end of file
+511958f703b21cc4a4080f4f5b6d34ead5e63371
\ No newline at end of file
diff --git a/rcmet/src/main/python/rcmes/cli/rcmet_ui.py b/rcmet/src/main/python/rcmes/cli/rcmet_ui.py
index f715fed..8cee16c 100755
--- a/rcmet/src/main/python/rcmes/cli/rcmet_ui.py
+++ b/rcmet/src/main/python/rcmes/cli/rcmet_ui.py
@@ -50,6 +50,11 @@
workDir, cacheDir = misc.getDirSettings()
temporalGrid = misc.getTemporalGrid()
spatialGrid = misc.getSpatialGrid()
+
+ # PER CLIMATE-179 - Guard against a bad spatialGrid Selection
+ while spatialGrid == False:
+ spatialGrid = misc.getSpatialGrid()
+
jobProperties = JobProperties(workDir, cacheDir, spatialGrid, temporalGrid)
# Section 1a: Enter model file/s
diff --git a/rcmet/src/main/python/rcmes/services/directory_helpers.py b/rcmet/src/main/python/rcmes/services/directory_helpers.py
index a4dc5a9..0479f09 100644
--- a/rcmet/src/main/python/rcmes/services/directory_helpers.py
+++ b/rcmet/src/main/python/rcmes/services/directory_helpers.py
@@ -48,6 +48,31 @@
else:
return returnJSON
+WORK_DIR = "/tmp/rcmet"
+
+@route('/getResultDirInfo')
+def getResultDirInfo():
+ dirPath = WORK_DIR
+ dirPath = dirPath.replace('/../', '/')
+ dirPath = dirPath.replace('/./', '/')
+
+ if os.path.isdir(dirPath):
+ listing = os.listdir(dirPath)
+ listingNoHidden = [f for f in listing if f[0] != '.']
+ joinedPaths = [os.path.join(dirPath, f) for f in listingNoHidden]
+ onlyFilesNoDirs = [f for f in joinedPaths if os.path.isfile(f)]
+ finalPaths = [p.replace(WORK_DIR, '') for p in onlyFilesNoDirs]
+ sorted(finalPaths, key=lambda s: s.lower())
+ returnJSON = finalPaths
+ else:
+ returnJSON = []
+
+ returnJSON = json.dumps(returnJSON)
+ if request.query.callback:
+ return "%s(%s)" % (request.query.callback, returnJSON)
+ else:
+ return returnJSON
+
@route('/getPathLeader/')
def getPathLeader():
returnJSON = {"leader": PATH_LEADER}
diff --git a/rcmet/src/main/python/rcmes/services/list_vars_in_file.py b/rcmet/src/main/python/rcmes/services/list_vars_in_file.py
index 3e32861..3a16777 100755
--- a/rcmet/src/main/python/rcmes/services/list_vars_in_file.py
+++ b/rcmet/src/main/python/rcmes/services/list_vars_in_file.py
@@ -59,8 +59,8 @@
print 'Error_reading_file '+filename
if success: #make some json
- var_name_list = json.dumps({'variables':f.variables.keys().encode() }, \
- sort_keys=True, indent=2)
+ var_name_list = json.dumps({'variables': f.variables.keys()},
+ sort_keys=True, indent=2)
if (request.query.callback):
return "%s(%s)" % (request.query.callback, var_name_list)
return var_name_list
diff --git a/rcmet/src/main/python/rcmes/storage/files.py.REMOVED.git-id b/rcmet/src/main/python/rcmes/storage/files.py.REMOVED.git-id
index 863f145..4e755e3 100644
--- a/rcmet/src/main/python/rcmes/storage/files.py.REMOVED.git-id
+++ b/rcmet/src/main/python/rcmes/storage/files.py.REMOVED.git-id
@@ -1 +1 @@
-4d1d834b058d4dba5c1289af634d361e575d6892
\ No newline at end of file
+f5116f16a7c8ffa36de8b6e10a6116943900c1cc
\ No newline at end of file
diff --git a/rcmet/src/main/python/rcmes/toolkit/do_data_prep.py.REMOVED.git-id b/rcmet/src/main/python/rcmes/toolkit/do_data_prep.py.REMOVED.git-id
index 892ff99..e76ae53 100644
--- a/rcmet/src/main/python/rcmes/toolkit/do_data_prep.py.REMOVED.git-id
+++ b/rcmet/src/main/python/rcmes/toolkit/do_data_prep.py.REMOVED.git-id
@@ -1 +1 @@
-89973b309365e54af318af96cb31afd8e80e6f41
\ No newline at end of file
+f9f5c2982515e671210c4db858f8adb2a3a3f5f2
\ No newline at end of file
diff --git a/rcmet/src/main/python/rcmes/toolkit/metrics.py.REMOVED.git-id b/rcmet/src/main/python/rcmes/toolkit/metrics.py.REMOVED.git-id
index 32af9ac..21cec8b 100644
--- a/rcmet/src/main/python/rcmes/toolkit/metrics.py.REMOVED.git-id
+++ b/rcmet/src/main/python/rcmes/toolkit/metrics.py.REMOVED.git-id
@@ -1 +1 @@
-69bab556012d8e82535248091cdaa0d0a9c9722b
\ No newline at end of file
+e432930085da59f77d6867a36b85a1148824e7f0
\ No newline at end of file
diff --git a/rcmet/src/main/python/rcmes/toolkit/process.py.REMOVED.git-id b/rcmet/src/main/python/rcmes/toolkit/process.py.REMOVED.git-id
index d676a5d..9b73f68 100644
--- a/rcmet/src/main/python/rcmes/toolkit/process.py.REMOVED.git-id
+++ b/rcmet/src/main/python/rcmes/toolkit/process.py.REMOVED.git-id
@@ -1 +1 @@
-c1f8bf1d26380195a38cdb8108128c3f23fc5205
\ No newline at end of file
+11dd9a55f5fb56da8a690876536f5872b1a70404
\ No newline at end of file
diff --git a/rcmet/src/main/python/rcmes/utils/misc.py.REMOVED.git-id b/rcmet/src/main/python/rcmes/utils/misc.py.REMOVED.git-id
index 7162413..7804d4f 100644
--- a/rcmet/src/main/python/rcmes/utils/misc.py.REMOVED.git-id
+++ b/rcmet/src/main/python/rcmes/utils/misc.py.REMOVED.git-id
@@ -1 +1 @@
-48777becb23e692f2dd693f448fbd42c8296f4e5
\ No newline at end of file
+14b6a2e95149f999a128c633e393a4bc834a5021
\ No newline at end of file
diff --git a/rcmet/src/main/python/tests/test_metrics.py b/rcmet/src/main/python/tests/test_metrics.py
new file mode 100644
index 0000000..07ac33e
--- /dev/null
+++ b/rcmet/src/main/python/tests/test_metrics.py
@@ -0,0 +1,52 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+import unittest
+
+import toolkit.metrics
+
+import numpy as np
+import numpy.ma as ma
+
+
+class TestCalcPdf(unittest.TestCase):
+
+ def testUsingSettingsKwarg(self):
+
+ # declare and initialize 1d arrays (mimick timeseries)
+ good_pdf = '0.091'
+
+ # declare and initialize 3d(time,lat,lon) type array
+ evaluationDataset = np.arange(0, 12, 0.5)
+ evaluationDataset = evaluationDataset.reshape(4, 2, 3)
+ evaluationDataset = ma.array(evaluationDataset)
+
+ referenceDataset = np.arange(10, 34)
+ referenceDataset = referenceDataset.reshape(4, 2, 3)
+ referenceDataset = ma.array(referenceDataset)
+
+ settings = (3, 10, 20)
+
+ pdf = '%.3f' % toolkit.metrics.calcPdf(evaluationDataset, referenceDataset, settings)
+ # Checking accuracy to 3 decimal places using a simple string comparison
+ self.assertEqual(pdf, good_pdf)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/rcmet/src/main/ui/app/css/app.css b/rcmet/src/main/ui/app/css/app.css
index 5b88486..c2a7c91 100755
--- a/rcmet/src/main/ui/app/css/app.css
+++ b/rcmet/src/main/ui/app/css/app.css
@@ -17,16 +17,22 @@
* under the License.
**/
-body
+#datasetDiv
{
- margin-left: 3%;
- margin-top: 3%;
+ height: 750px;
+ overflow-y: auto;
+ overflow-x: hidden;
}
#map
{
height: 500px;
- width: 100%;
+}
+
+/* Small preview map that is displayed alongside dataset information */
+.preview-map {
+ height: 100px;
+ width: 100px;
}
.small-alert
@@ -37,15 +43,32 @@
margin-left: 10px;
}
+.colorSquare
+{
+ margin-top: 3px;
+ height: 10px;
+ width: 10px;
+}
+
ul
{
list-style-type: none;
}
-.btn-link.no-color-link {color:#000000;}
-.btn-link.no-color-link:hover {color:#000000; text-decoration: none;}
-.btn-link.no-color-link:visited {color:#000000;}
-.btn-link.no-color-link:active {color:#000000;}
+.no-color-link {color:#000000;}
+.no-color-link:hover {color:#000000; text-decoration: none;}
+.no-color-link:visited {color:#000000;}
+.no-color-link:active {color:#000000;}
+
+/* Remove the grayed out close button in modal headers */
+.modal-header .close {
+ opacity: 1;
+}
+
+/* Remove the grayed out close button in modal footers */
+.modal-footer .close {
+ opacity: 1;
+}
/**
* Timeline
diff --git a/rcmet/src/main/ui/app/img/globe.png.REMOVED.git-id b/rcmet/src/main/ui/app/img/globe.png.REMOVED.git-id
new file mode 100644
index 0000000..a0d131b
--- /dev/null
+++ b/rcmet/src/main/ui/app/img/globe.png.REMOVED.git-id
@@ -0,0 +1 @@
+5099b4e2d911e5e0a4e7b33b289bf7aa1d2eab55
\ No newline at end of file
diff --git a/rcmet/src/main/ui/app/index.html.REMOVED.git-id b/rcmet/src/main/ui/app/index.html.REMOVED.git-id
index f7fd2a9..5040707 100644
--- a/rcmet/src/main/ui/app/index.html.REMOVED.git-id
+++ b/rcmet/src/main/ui/app/index.html.REMOVED.git-id
@@ -1 +1 @@
-985d4326ab13e30e26980927a3d7a5c2d9e369a4
\ No newline at end of file
+f2b99de30e98bcf70cd141f25cd145ba8d0372ec
\ No newline at end of file
diff --git a/rcmet/src/main/ui/app/js/app.js b/rcmet/src/main/ui/app/js/app.js
index fd5841a..09ea536 100755
--- a/rcmet/src/main/ui/app/js/app.js
+++ b/rcmet/src/main/ui/app/js/app.js
@@ -28,7 +28,7 @@
App.Controllers = angular.module('ocw.controllers', []);
App.Filters = angular.module('ocw.filters', []);
-angular.module('ocw', ['ocw.services', 'ocw.directives', 'ocw.controllers', 'ocw.filters', 'ui.date']).
+angular.module('ocw', ['ocw.services', 'ocw.directives', 'ocw.controllers', 'ocw.filters', 'ui.date', 'ui.bootstrap']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/obs', {templateUrl: 'partials/selectObservation.html', controller: 'ObservationSelectCtrl'}).
diff --git a/rcmet/src/main/ui/app/js/controllers/ParameterSelectCtrl.js b/rcmet/src/main/ui/app/js/controllers/ParameterSelectCtrl.js
index fed07d5..3fd47c7 100644
--- a/rcmet/src/main/ui/app/js/controllers/ParameterSelectCtrl.js
+++ b/rcmet/src/main/ui/app/js/controllers/ParameterSelectCtrl.js
@@ -163,7 +163,7 @@
$scope.runningEval = false;
$timeout(function() {
- $('#evaluationResults').trigger('modalOpen', true, true);
+ window.location = "/app/results.html";
}, 100);
}).error(function() {
$scope.runningEval = false;
diff --git a/rcmet/src/main/ui/app/js/controllers/RcmedSelectionCtrl.js b/rcmet/src/main/ui/app/js/controllers/RcmedSelectionCtrl.js
index bee3c3a..0f8430b 100644
--- a/rcmet/src/main/ui/app/js/controllers/RcmedSelectionCtrl.js
+++ b/rcmet/src/main/ui/app/js/controllers/RcmedSelectionCtrl.js
@@ -76,8 +76,10 @@
// Save the parameter id (the important part) and name (for display purposes)
newDataset['param'] = $scope.parameterSelection['parameter_id'];
newDataset['paramName'] = $scope.parameterSelection['longname'];
- // Save the (fake) lat/lon information. Our datasets cover the entire globe (I think...)
- newDataset['latlonVals'] = {"latMin": -90, "latMax": 90, "lonMin": -180, "lonMax": 180};
+ // Save the (fake) lat/lon information. We test with the TRMM dataset. RCMED currently
+ // doesn't return bounding information. This functionality is being added soon. When that
+ // is the case these hard coded values should be removed.
+ newDataset['latlonVals'] = {"latMin": -49.875, "latMax": 49.875, "lonMin": -179.875, "lonMax": 179.875};
// Set some defaults for lat/lon variable names. This just helps us display stuff later.
newDataset['lat'] = "N/A";
newDataset['lon'] = "N/A";
diff --git a/rcmet/src/main/ui/app/js/controllers/ResultCtrl.js b/rcmet/src/main/ui/app/js/controllers/ResultCtrl.js
new file mode 100644
index 0000000..414ad2a
--- /dev/null
+++ b/rcmet/src/main/ui/app/js/controllers/ResultCtrl.js
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http: *www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+**/
+
+// Controller for result page
+App.Controllers.controller('ResultCtrl', ['$rootScope', '$scope', '$http',
+function($rootScope, $scope, $http) {
+
+ // Grab all figures
+ $scope.figures = [];
+ $http.jsonp($rootScope.baseURL + '/getResultDirInfo?callback=JSON_CALLBACK').
+ success(function(data) {
+ $scope.figures = data;
+ });
+}]);
diff --git a/rcmet/src/main/ui/app/js/controllers/SettingsCtrl.js b/rcmet/src/main/ui/app/js/controllers/SettingsCtrl.js
index 7c24945..a32a9cb 100755
--- a/rcmet/src/main/ui/app/js/controllers/SettingsCtrl.js
+++ b/rcmet/src/main/ui/app/js/controllers/SettingsCtrl.js
@@ -17,7 +17,8 @@
* under the License.
**/
-App.Controllers.controller('SettingsCtrl', ['$scope', 'evaluationSettings',
-function($scope, evaluationSettings) {
+App.Controllers.controller('SettingsCtrl', ['$scope', 'evaluationSettings', 'selectedDatasetInformation',
+function($scope, evaluationSettings, selectedDatasetInformation) {
$scope.settings = evaluationSettings.getSettings();
+ $scope.datasets = selectedDatasetInformation.getDatasets();
}]);
diff --git a/rcmet/src/main/ui/app/js/controllers/TimelineCtrl.js b/rcmet/src/main/ui/app/js/controllers/TimelineCtrl.js
index 283e384..9485aa4 100644
--- a/rcmet/src/main/ui/app/js/controllers/TimelineCtrl.js
+++ b/rcmet/src/main/ui/app/js/controllers/TimelineCtrl.js
@@ -28,68 +28,58 @@
}
// Don't process if no datasets have been added
- if ($scope.datasets.length == 0)
+ if ($scope.datasets.length == 0 || !("timeline" in $rootScope))
return;
- if ("timeline" in $rootScope) {
-
- // Create DataTable to add data to timeline
- var data = new google.visualization.DataTable();
- data.addColumn('datetime', 'start');
- data.addColumn('datetime', 'end');
- data.addColumn('string', 'content');
+ // Create DataTable to add data to timeline
+ var data = new google.visualization.DataTable();
+ data.addColumn('datetime', 'start');
+ data.addColumn('datetime', 'end');
+ data.addColumn('string', 'content');
- // Loop through datasets and add data to timeline
- var i = -1;
- angular.forEach($scope.datasets, function(dataset) {
+ // Loop through datasets and find the overlapping start/end time range
+ var start = $scope.datasets[0].timeVals.start;
+ var end = $scope.datasets[0].timeVals.end;
+ for (var i = 0; i < $scope.datasets.length; i++) {
+ var possibleNewStart = $scope.datasets[i].timeVals.start;
+ var possibleNewEnd = $scope.datasets[i].timeVals.end;
- // Keep track of dataset count for displaying colors
- i++;
-
- /* TODO should "disable overlay" also disable timeline? */
+ start = (possibleNewStart > start) ? possibleNewStart : start;
+ end = (possibleNewEnd < end) ? possibleNewEnd : end;
+ }
- // Get time bounds from dataset
- var start = dataset.timeVals.start;
- var end = dataset.timeVals.end;
+ // Set the timeline extent to the overlapping time range
+ //
+ // NOTE: The month value substring is expected to be 0-based (hence the -1)
+ $rootScope.timeline.setVisibleChartRange(new Date(start.substr(0, 4), start.substr(5, 2) - 1, start.substr(8, 2)),
+ new Date(end.substr(0, 4), end.substr(5, 2) - 1, end.substr(8, 2)));
- // Add different color to each bar
- var style = 'background-color:' + $rootScope.fillColors[i] +
- '; border-color:' + $rootScope.surroundColors[i] + ';';
- var ocwBar = '<div class="ocw-bar timeline-event-range" style="' + style + '"></div>';
-
- // Add row to DataTable: object with start and end date
- // note: subtract one from month since indexes from 0 to 11
- data.addRow([new Date(start.substr(0,4), start.substr(5,2)-1, start.substr(8,2)),
- new Date(end.substr(0,4), end.substr(5,2)-1, end.substr(8,2)),
- ocwBar ]);
- });
+ // Add user selected bounds to timeline
+ if ($scope.regionParams.areValid) {
- // Add user selected bounds to timeline
- if ($scope.regionParams.areValid) {
+ var userStart = $scope.regionParams.start;
+ var userEnd = $scope.regionParams.end;
- var userStart = $scope.regionParams.start;
- var userEnd = $scope.regionParams.end;
-
- // Add color to user selected bounds
- var style = 'background-color: #000000; border: 2px solid;';
- var ocwBar = '<div class="ocw-bar timeline-event-range" style="' + style + '"></div>';
-
- // Add row to DataTable: object with start and end date
- // note: subtract one from month since indexes from 0 to 11
- data.addRow([new Date(userStart.substr(0,4), userStart.substr(5,2)-1, userStart.substr(8,2)),
- new Date(userEnd.substr(0,4), userEnd.substr(5,2)-1, userEnd.substr(8,2)),
- ocwBar ]);
- }
-
- var options = {
- 'minHeight': "200px",
- 'width': "99.8%",
- 'zoomable': false
- };
+ // Add color to user selected bounds
+ var style = 'background-color: #000000; border: 2px solid;';
+ var ocwBar = '<div class="ocw-bar timeline-event-range" style="' + style + '"></div>';
- // Draw timeline with data (DataTable) and options (a name-value map)
- $rootScope.timeline.draw(data, options);
- }
+ // Add row to DataTable: object with start and end date
+ // note: subtract one from month since indexes from 0 to 11
+ data.addRow([new Date(userStart.substr(0,4), userStart.substr(5,2)-1, userStart.substr(8,2)),
+ new Date(userEnd.substr(0,4), userEnd.substr(5,2)-1, userEnd.substr(8,2)),
+ ocwBar ]);
+ }
+
+ var options = {
+ "width": "100%",
+ "showCurrentTime": false,
+ "moveable": false,
+ "zoomable": false,
+ };
+
+ // Draw timeline with data (DataTable) and options (a name-value map)
+ $rootScope.timeline.draw(data, options);
};
$scope.$on('redrawOverlays', function(event, parameters) {
diff --git a/rcmet/src/main/ui/app/js/controllers/WorldMapCtrl.js b/rcmet/src/main/ui/app/js/controllers/WorldMapCtrl.js
index 782ccdd..3de155c 100644
--- a/rcmet/src/main/ui/app/js/controllers/WorldMapCtrl.js
+++ b/rcmet/src/main/ui/app/js/controllers/WorldMapCtrl.js
@@ -29,56 +29,60 @@
$rootScope.rectangleGroup.clearLayers();
}
- // Don't process if we don't have any datasets added!!
- if ($scope.datasets.length == 0)
+ // Don't process if we don't have any datasets added or if the map doesn't exist!!
+ if ($scope.datasets.length == 0 || !("map" in $rootScope))
return;
- if ("map" in $rootScope) {
- // Create Group to add all rectangles to map
- $rootScope.rectangleGroup = L.layerGroup();
-
- // Loop through datasets and add rectangles to Group
- var i = -1;
- angular.forEach($scope.datasets, function(dataset) {
- // Keep track of dataset count for displaying colors
- i++;
+ // Create a group that we'll draw overlays to
+ $rootScope.rectangleGroup = L.layerGroup();
+ // Add rectangle Group to map
+ $rootScope.rectangleGroup.addTo($rootScope.map);
- // If the user disabled the overlay then get out of here!
- if (!dataset.shouldDisplay)
- return;
+ // Calculate the overlap region and set the map to show the new overlap
+ var latMin = -90,
+ latMax = 90,
+ lonMin = -180,
+ lonMax = 180;
- // Get bounds from dataset
- var maplatlon = dataset.latlonVals;
- var bounds = [[maplatlon.latMax, maplatlon.lonMin], [maplatlon.latMin, maplatlon.lonMax]];
+ // Get the valid lat/lon range in the selected datasets.
+ for (var i = 0; i < selectedDatasetInformation.getDatasetCount(); i++) {
+ var curDataset = $scope.datasets[i];
- var polygon = L.rectangle(bounds,{
- stroke: false,
- fillColor: $rootScope.fillColors[i],
- fillOpacity: 0.3
- });
+ latMin = (curDataset['latlonVals']['latMin'] > latMin) ? curDataset['latlonVals']['latMin'] : latMin;
+ latMax = (curDataset['latlonVals']['latMax'] < latMax) ? curDataset['latlonVals']['latMax'] : latMax;
+ lonMin = (curDataset['latlonVals']['lonMin'] > lonMin) ? curDataset['latlonVals']['lonMin'] : lonMin;
+ lonMax = (curDataset['latlonVals']['lonMax'] < lonMax) ? curDataset['latlonVals']['lonMax'] : lonMax;
+ }
- // Add layer to Group
- $rootScope.rectangleGroup.addLayer(polygon);
- });
+ var overlapBounds = [[latMax, lonMin], [latMin, lonMax]];
+ $rootScope.map.fitBounds(overlapBounds, {padding: [0, 0]});
- // Draw user selected region
- if ($scope.regionParams.areValid) {
+ // Draw border around overlap region
+ var overlapBorder = L.rectangle(overlapBounds, {
+ color: '#000000',
+ opacity: 1.0,
+ fill: false,
+ weight: 2,
+ dashArray: "10 10",
+ });
- var bounds = [[$scope.regionParams.latMax, $scope.regionParams.lonMin],
- [$scope.regionParams.latMin, $scope.regionParams.lonMax]];
+ $rootScope.rectangleGroup.addLayer(overlapBorder);
- var polygon = L.rectangle(bounds, {
- color: '#000000',
- opacity: 1.0,
- fill: false,
- });
+ // Draw user selected region
+ if ($scope.regionParams.areValid) {
- $rootScope.rectangleGroup.addLayer(polygon);
- }
+ var bounds = [[$scope.regionParams.latMax, $scope.regionParams.lonMin],
+ [$scope.regionParams.latMin, $scope.regionParams.lonMax]];
- // Add rectangle Group to map
- $rootScope.rectangleGroup.addTo($rootScope.map);
- }
+ var polygon = L.rectangle(bounds, {
+ color: '#000000',
+ opacity: .3,
+ stroke: false,
+ fill: true,
+ });
+
+ $rootScope.rectangleGroup.addLayer(polygon);
+ }
};
$scope.$on('redrawOverlays', function(event, parameters) {
diff --git a/rcmet/src/main/ui/app/js/directives/LeafletMap.js b/rcmet/src/main/ui/app/js/directives/LeafletMap.js
index dcdea74..bd56801 100644
--- a/rcmet/src/main/ui/app/js/directives/LeafletMap.js
+++ b/rcmet/src/main/ui/app/js/directives/LeafletMap.js
@@ -28,11 +28,12 @@
center: [40, 0],
zoom: 2,
scrollWheelZoom: false,
+ attributionControl: false,
+ worldCopyJump: true,
});
+
//create a CloudMade tile layer and add it to the map
- L.tileLayer('http://{s}.tile.cloudmade.com/57cbb6ca8cac418dbb1a402586df4528/997/256/{z}/{x}/{y}.png', {
- maxZoom: 4, minZoom: 2,
- }).addTo($rootScope.map);
+ L.tileLayer('http://{s}.tile.cloudmade.com/57cbb6ca8cac418dbb1a402586df4528/997/256/{z}/{x}/{y}.png', {}).addTo($rootScope.map);
}
};
});
diff --git a/rcmet/src/main/ui/app/js/directives/PreviewMap.js b/rcmet/src/main/ui/app/js/directives/PreviewMap.js
new file mode 100644
index 0000000..f46b897
--- /dev/null
+++ b/rcmet/src/main/ui/app/js/directives/PreviewMap.js
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http: *www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+**/
+
+App.Directives.directive('previewMap', function($rootScope) {
+ return {
+ restrict: 'A',
+ replace: true,
+ scope: {dataset: '=previewMap', index: '=index'},
+ template: '<div id="{{dataset.name}}" class="preview-map"></div>',
+ replace: true,
+ link: function(scope, element, attrs) {
+
+ // Any attribute that contains {{}} interpolation will be set to null in the attrs
+ // parameter during the link function since the first $digest since the compilation
+ // has yet to run to evaluate it! We can't run a $digest in the middle of compilation,
+ // so using an $observe (or $watch) is the best way to get the values.
+ attrs.$observe('id', function(newId) {
+ var map = L.map(attrs.id, {
+ zoom: 0,
+ scrollWheelZoom: false,
+ zoomControl: false,
+ attributionControl: false,
+ worldCopyJump: true,
+ });
+
+ //create a CloudMade tile layer and add it to the map
+ L.tileLayer('http://{s}.tile.cloudmade.com/57cbb6ca8cac418dbb1a402586df4528/997/256/{z}/{x}/{y}.png', {}).addTo(map);
+
+ // Zoom the map to the dataset bound regions (or at least try our best to do so)
+ var datasetBounds = [[scope.dataset.latlonVals.latMax, scope.dataset.latlonVals.lonMin],
+ [scope.dataset.latlonVals.latMin, scope.dataset.latlonVals.lonMax]];
+ map.fitBounds(datasetBounds, {});
+
+ // Draw a colored overlay on the region of the map
+ var maplatlon = scope.dataset.latlonVals;
+ var bounds = [[maplatlon.latMax, maplatlon.lonMin], [maplatlon.latMin, maplatlon.lonMax]];
+
+ var polygon = L.rectangle(bounds,{
+ stroke: false,
+ fillColor: $rootScope.fillColors[1],
+ fillOpacity: 0.6
+ });
+
+ // Add layer to Group
+ var rectangleGroup = L.layerGroup();
+ rectangleGroup.addLayer(polygon);
+
+ // Add the overlay to the map
+ rectangleGroup.addTo(map);
+ });
+ }
+ };
+});
diff --git a/rcmet/src/main/ui/app/js/directives/Timeline.js b/rcmet/src/main/ui/app/js/directives/Timeline.js
index a47966c..fa7abe4 100644
--- a/rcmet/src/main/ui/app/js/directives/Timeline.js
+++ b/rcmet/src/main/ui/app/js/directives/Timeline.js
@@ -16,7 +16,7 @@
//
// Directive for dealing with the Leaflet map
-App.Directives.directive('timeline', function($rootScope) {
+App.Directives.directive('timeline', function($rootScope, $window) {
return {
restrict: 'C',
replace: true,
@@ -29,6 +29,20 @@
function initTimeline() {
// Instantiate timeline object.
$rootScope.timeline = new links.Timeline(document.getElementById('OCWtimeline'));
+
+ // Redraw the timeline whenever the window is resized
+ angular.element($window).bind('resize', function() {
+ $rootScope.timeline.checkResize();
+ });
+
+ var options = {
+ "width": "100%",
+ "showCurrentTime": false,
+ "moveable": false,
+ "zoomable": false
+ };
+
+ $rootScope.timeline.draw([], options);
}
}
}
diff --git a/rcmet/src/main/ui/app/js/lib/angular-ui/angular-ui-0.4-tpls.js.REMOVED.git-id b/rcmet/src/main/ui/app/js/lib/angular-ui/angular-ui-0.4-tpls.js.REMOVED.git-id
new file mode 100644
index 0000000..e99ceab
--- /dev/null
+++ b/rcmet/src/main/ui/app/js/lib/angular-ui/angular-ui-0.4-tpls.js.REMOVED.git-id
@@ -0,0 +1 @@
+76dd8f424aec88e2b44b83907f3031f161e1a190
\ No newline at end of file
diff --git a/rcmet/src/main/ui/app/js/services/EvaluationSettings.js b/rcmet/src/main/ui/app/js/services/EvaluationSettings.js
index 7dd8e69..c2330b6 100755
--- a/rcmet/src/main/ui/app/js/services/EvaluationSettings.js
+++ b/rcmet/src/main/ui/app/js/services/EvaluationSettings.js
@@ -27,6 +27,7 @@
'options': ['daily', 'monthly', 'yearly'],
'selected': 'monthly',
},
+ 'spatialSelect': '',
};
return {
diff --git a/rcmet/src/main/ui/app/js/services/SelectedDatasetInformation.js b/rcmet/src/main/ui/app/js/services/SelectedDatasetInformation.js
index af3eaba..8378212 100644
--- a/rcmet/src/main/ui/app/js/services/SelectedDatasetInformation.js
+++ b/rcmet/src/main/ui/app/js/services/SelectedDatasetInformation.js
@@ -33,7 +33,7 @@
addDataset: function(dataset) {
// All datasets need a shouldDisplay attribute that is used when rendering
// the overlays on the map!
- dataset.shouldDisplay = true;
+ dataset.shouldDisplay = false;
// The regrid attribute indicates which dataset should be used for spatial regridding
dataset.regrid = false;
diff --git a/rcmet/src/main/ui/app/results.html b/rcmet/src/main/ui/app/results.html
new file mode 100755
index 0000000..69a7c66
--- /dev/null
+++ b/rcmet/src/main/ui/app/results.html
@@ -0,0 +1,68 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
+<!doctype html>
+<html lang="en" ng-app="ocw" ng-controller="ResultCtrl">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>OCW UI - Results</title>
+ <link rel="stylesheet" href="css/lib/bootstrap.min.css"/>
+ <link rel="stylesheet" href="css/lib/bootstrap-responsive.min.css"/>
+ <link rel="stylesheet" href="css/lib/font-awesome.min.css"/>
+ <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/ui-lightness/jquery-ui.min.css" type="text/css"/>
+ <!--[if lte IE 8]>
+ <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.5/leaflet.ie.css" />
+ <![endif]-->
+ <link rel="stylesheet" href="css/app.css"/>
+</head>
+<body>
+
+<div class="container-fluid">
+ <div class="row-fluid">
+ <div class="row span12 text-center">
+ <h2>Apache Open Climate Workbench UI - Results</h2>
+ <hr />
+ </div>
+ <div class="row-fluid text-center">
+ <ul>
+ <li ng-repeat="figure in figures">
+ <img src="{{baseURL}}/static/evalResults{{figure}}" alt="" />
+ </li>
+ </ul>
+ </div>
+ </div>
+</div>
+
+ <!--Libraries-->
+ <script src="js/lib/jquery/jquery-1.10.1.js"></script>
+ <script src="js/lib/jquery/jquery-ui/jquery-ui-1.10.3.min.js"></script>
+ <script src="js/lib/angular/angular.min.js"></script>
+ <script src="js/lib/angular-ui/angular-ui-0.4-tpls.js"></script>
+ <script src="js/lib/jquery/jquery-ui/datepicker-wrapper/date.js"></script>
+ <script src="js/lib/bootstrap/bootstrap.js"></script>
+
+ <!--General-->
+ <script src="js/app.js"></script>
+
+ <!--Controllers-->
+ <script src="js/controllers/ResultCtrl.js"></script>
+
+</body>
+</html>
diff --git a/rcmet/src/main/ui/config/karma.conf.js b/rcmet/src/main/ui/config/karma.conf.js
index e9491a5..65b5013 100755
--- a/rcmet/src/main/ui/config/karma.conf.js
+++ b/rcmet/src/main/ui/config/karma.conf.js
@@ -26,6 +26,7 @@
'app/js/lib/bootstrap/bootstrap.js',
'app/js/lib/angular/angular.js',
'app/js/lib/angular/angular-*.js',
+ 'app/js/lib/angular-ui/*.js',
'test/lib/angular/angular-mocks.js',
'app/js/lib/jquery/jquery-ui/datepicker-wrapper/date.js',
'app/js/lib/leaflet/leaflet-0.5.js',
diff --git a/rcmet/src/main/ui/test/unit/controllers/SettingsCtrlTest.js b/rcmet/src/main/ui/test/unit/controllers/SettingsCtrlTest.js
index f3a558e..12c133d 100644
--- a/rcmet/src/main/ui/test/unit/controllers/SettingsCtrlTest.js
+++ b/rcmet/src/main/ui/test/unit/controllers/SettingsCtrlTest.js
@@ -30,7 +30,17 @@
var scope = $rootScope.$new();
var ctrl = $controller("SettingsCtrl", {$scope: scope});
- expect(Object.keys(scope.settings)).toEqual(["metrics", "temporal"]);
+ expect(Object.keys(scope.settings)).toEqual(["metrics", "temporal", "spatialSelect"]);
+ });
+ });
+
+ it('should pull the dataset information', function() {
+ inject(function($rootScope, $controller) {
+ var scope = $rootScope.$new();
+ var ctrl = $controller("SettingsCtrl", {$scope: scope});
+
+ expect(typeof scope.datasets).toBe('object');
+ expect(Object.keys(scope.datasets).length).toBe(0);
});
});
});
diff --git a/rcmet/src/main/ui/test/unit/controllers/WorldMapCtrlTest.js b/rcmet/src/main/ui/test/unit/controllers/WorldMapCtrlTest.js
index a6659eb..805dc88 100644
--- a/rcmet/src/main/ui/test/unit/controllers/WorldMapCtrlTest.js
+++ b/rcmet/src/main/ui/test/unit/controllers/WorldMapCtrlTest.js
@@ -35,7 +35,8 @@
// Don't try to add the user defined region since we don't have one
scope.regionParams.areValid = false;
// We need to fake the map object. The only thing we care about is faking the "addLayer" function
- $rootScope.map = {addLayer: function(){}};
+ // and the "fitBounds" functions which our map controllers makes use of.
+ $rootScope.map = {addLayer: function(){}, fitBounds: function(){}};
$rootScope.fillColors = ['#ff0000'];
expect("rectangleGroup" in $rootScope).toBe(false);
diff --git a/rcmet/src/main/ui/test/unit/directives/PreviewMapTest.js b/rcmet/src/main/ui/test/unit/directives/PreviewMapTest.js
new file mode 100644
index 0000000..a7991e6
--- /dev/null
+++ b/rcmet/src/main/ui/test/unit/directives/PreviewMapTest.js
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+**/
+
+'use strict';
+
+describe('directives', function() {
+ beforeEach(module('ocw'));
+
+ describe('preview-map directive', function() {
+ it('should set the proper class', function() {
+ inject(function($compile, $rootScope) {
+ $rootScope.dataset = {latlonVals: {latMax: 90, lonMax: 90, latMin: -90, lonMin: -90}, name: "TRMM"};
+
+ var element = $compile('<div preview-map="dataset"></div>')($rootScope);
+
+ expect(element.hasClass("preview-map")).toBeTruthy();
+ });
+ });
+
+ it('should set the id of the template to the name of the dataset', function() {
+ inject(function($compile, $rootScope) {
+ $rootScope.dataset = {latlonVals: {latMax: 90, lonMax: 90, latMin: -90, lonMin: -90}, name: "TRMM"};
+
+ var element = $compile('<div preview-map="dataset"></div>')($rootScope);
+
+ expect(element.attr('id')).toEqual("{{dataset.name}}");
+ });
+ });
+ });
+});
diff --git a/rcmet/src/main/ui/test/unit/services/SelectedDatasetInfomationTest.js b/rcmet/src/main/ui/test/unit/services/SelectedDatasetInfomationTest.js
index fa0e027..aeada3d 100644
--- a/rcmet/src/main/ui/test/unit/services/SelectedDatasetInfomationTest.js
+++ b/rcmet/src/main/ui/test/unit/services/SelectedDatasetInfomationTest.js
@@ -53,7 +53,7 @@
it('should set the shouldDisplay attribute when adding a dataset', function() {
inject(function(selectedDatasetInformation) {
selectedDatasetInformation.addDataset({});
- expect(selectedDatasetInformation.getDatasets()[0].shouldDisplay).toBe(true);
+ expect(selectedDatasetInformation.getDatasets()[0].shouldDisplay).toBe(false);
});
});