-
-
Notifications
You must be signed in to change notification settings - Fork 278
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ht 38 select task #51
Changes from 8 commits
531473b
e23208c
30f81c6
240cf2b
7ca3186
80f0f6e
18b3d53
883f971
c64d5de
b7e6f5f
50d3e9f
292e0e5
0b34ada
c1a3f55
5aed934
44be3c2
071aff5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,37 +7,98 @@ | |
*/ | ||
angular | ||
.module('taskingManager') | ||
.controller('projectController', ['$location', 'mapService', 'projectService', 'styleService', projectController]); | ||
.controller('projectController', ['$scope', '$location', 'mapService', 'projectService', 'styleService', projectController]); | ||
|
||
function projectController($location, mapService, projectService, styleService) { | ||
function projectController($scope, $location, mapService, projectService, styleService) { | ||
var vm = this; | ||
vm.project = null; | ||
vm.map = null; | ||
vm.currentTab = ''; | ||
vm.mappingStep = ''; | ||
|
||
//selected task | ||
vm.selectedTask = null; | ||
vm.isSelectTaskMappable = false; | ||
|
||
//interaction | ||
var select = new ol.interaction.Select({ | ||
style: styleService.getSelectedStyleFunction | ||
}); | ||
|
||
activate(); | ||
|
||
function activate() { | ||
//TODO: Set up sidebar tabs | ||
vm.currentTab = 'description'; | ||
vm.mappingStep = 'select'; | ||
mapService.createOSMMap('map'); | ||
vm.map = mapService.getOSMMap(); | ||
|
||
vm.map.addInteraction(select); | ||
select.on('select', function (event) { | ||
$scope.$apply(function () { | ||
var feature = event.selected[0]; | ||
onTaskSelection(feature); | ||
}); | ||
}); | ||
|
||
var id = $location.search().project; | ||
initialiseProject(id); | ||
//TODO: put the project metadata (description instructions on disebar tabs | ||
//TODO: put the project metadata (description instructions on siedbar tabs | ||
} | ||
|
||
vm.selectRandomTask = function () { | ||
var task = getRandomMappableTask(vm.project.tasks); | ||
if (task) { | ||
//iterate layers to find task layer | ||
var layers = vm.map.getLayers(); | ||
for (var i = 0; i < layers.getLength(); i++) { | ||
if (layers.item(i).get('name') === 'tasks') { | ||
var feature = layers.item(i).getSource().getFeatures().filter(function (feature) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of iterating over the layers, you could store the vector layer as a controller variable and reference it directly. |
||
if (feature.get('taskId') === task.properties.taskId) { | ||
// TODO the next few steps might be better done with event handling and dispatching to resuse | ||
// through the listener code on the select interaction. Need to find a way to do that | ||
select.getFeatures().clear(); | ||
select.getFeatures().push(feature); | ||
onTaskSelection(feature); | ||
var vPadding = vm.map.getSize()[1] * 0.3; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Explain with a comment what this magic number is exactly |
||
vm.map.getView().fit(feature.getGeometry().getExtent(), {padding: [vPadding, vPadding, vPadding, vPadding]}); | ||
} | ||
}); | ||
break; | ||
} | ||
} | ||
} | ||
else { | ||
vm.selectedTask = null; | ||
vm.isSelectTaskMappable = false; | ||
vm.mappingStep = 'none-available'; | ||
} | ||
}; | ||
|
||
/** | ||
* Get a project with using it's id | ||
* clears the currently selected task. Clears down/resets the vm properties and clears the feature param in the select interaction object. | ||
*/ | ||
function initialiseProject(id){ | ||
vm.clearCurrentSelection = function () { | ||
vm.selectedTask = null; | ||
vm.isSelectTaskMappable = false; | ||
vm.currentTab = 'mapping'; | ||
vm.mappingStep = 'select'; | ||
select.getFeatures().clear(); | ||
}; | ||
|
||
/** | ||
* Initilaise a project with using it's id | ||
* @param id - id of the project to initialise | ||
*/ | ||
function initialiseProject(id) { | ||
var resultsPromise = projectService.getProject(id); | ||
resultsPromise.then(function (data) { | ||
//project returned successfully | ||
vm.project = data; | ||
addAoiToMap(vm.project.areaOfInterest); | ||
addProjectTasksToMap(vm.project.tasks); | ||
}, function(){ | ||
}, function () { | ||
// project not returned successfully | ||
// TODO - may want to handle error | ||
}); | ||
|
@@ -47,11 +108,12 @@ | |
* Adds project tasks to map as features from geojson | ||
* @param tasks | ||
*/ | ||
function addProjectTasksToMap(tasks){ | ||
function addProjectTasksToMap(tasks) { | ||
//TODO: may want to refactor this into a service at some point so that it can be reused | ||
var source = new ol.source.Vector(); | ||
var vector = new ol.layer.Vector({ | ||
source: source, | ||
name: 'tasks', | ||
style: styleService.getTaskStyleFunction | ||
}); | ||
vm.map.addLayer(vector); | ||
|
@@ -70,11 +132,12 @@ | |
* Adds the aoi feature to the map | ||
* @param aoi | ||
*/ | ||
function addAoiToMap(aoi){ | ||
function addAoiToMap(aoi) { | ||
//TODO: may want to refactor this into a service at some point so that it can be resused | ||
var source = new ol.source.Vector(); | ||
var vector = new ol.layer.Vector({ | ||
source: source | ||
source: source, | ||
name: 'aoi' | ||
}); | ||
vm.map.addLayer(vector); | ||
|
||
|
@@ -86,5 +149,48 @@ | |
}); | ||
source.addFeature(aoiFeatures); | ||
} | ||
|
||
/** | ||
* returns a randomly selected mappable task from the passed in tasks JSON object | ||
* @param tasks - the set of tasks from which to find a random task | ||
* @returns task if one found, null if non available | ||
*/ | ||
function getRandomMappableTask(tasks) { | ||
|
||
// get all non locked ready tasks, | ||
var candidates = [] | ||
var candidates = tasks.features.filter(function (item) { | ||
if (!item.properties.taskLocked && item.properties.taskStatus === 'READY') return item; | ||
}); | ||
// if no ready tasks, get non locked invalid tasks | ||
if (candidates.length == 0) { | ||
candidates = tasks.features.filter(function (item) { | ||
if (!item.properties.taskLocked && item.properties.taskStatus === 'INVALIDATED') return item; | ||
}); | ||
} | ||
|
||
// if tasks were found, return a random task | ||
if (candidates.length > 0) { | ||
return candidates[Math.floor((Math.random() * (candidates.length - 1)))]; | ||
} | ||
|
||
// if all else fails, return null | ||
return null; | ||
} | ||
|
||
/** | ||
* Sets up the model for currently selected feature | ||
* @param feature | ||
*/ | ||
function onTaskSelection(feature) { | ||
var taskStatus = feature.get('taskStatus'); | ||
var taskLocked = feature.get('taskLocked') | ||
vm.selectedTask = feature; | ||
vm.isSelectTaskMappable = !taskLocked && (taskStatus === 'READY' || taskStatus === 'INVALIDATED'); | ||
vm.currentTab = 'mapping'; | ||
vm.mappingStep = 'view'; | ||
} | ||
|
||
|
||
} | ||
})(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,22 +10,112 @@ <h1 class="section__title"> | |
<div class="create-project"> | ||
<div class="sidebar"> | ||
<div class="button-group button-group--horizontal" role="group" aria-label="..."> | ||
<button ng-click="projectCtrl.currentTab = 'description'" class="button button--achromic" type="button" ng-class="projectCtrl.currentTab == 'description'? 'button--active':''">Description</button> | ||
<button ng-click="projectCtrl.currentTab = 'instructions'" class="button button--achromic" type="button" ng-class="projectCtrl.currentTab == 'instructions'? 'button--active':''">Instructions</button> | ||
<button ng-click="projectCtrl.currentTab = 'mapping'"class="button button--achromic" type="button" ng-class="projectCtrl.currentTab == 'mapping'? 'button--active':''">*Mapping*</button> | ||
<button ng-click="projectCtrl.currentTab = 'description'" class="button button--achromic" | ||
type="button" ng-class="projectCtrl.currentTab == 'description'? 'button--active':''"> | ||
Description | ||
</button> | ||
<button ng-click="projectCtrl.currentTab = 'instructions'" class="button button--achromic" | ||
type="button" ng-class="projectCtrl.currentTab == 'instructions'? 'button--active':''"> | ||
Instructions | ||
</button> | ||
<button ng-click="projectCtrl.currentTab = 'mapping'" class="button button--achromic" type="button" | ||
ng-class="projectCtrl.currentTab == 'mapping'? 'button--active':''">Mapping | ||
</button> | ||
</div> | ||
<div ng-show="projectCtrl.currentTab === 'description'"> | ||
<h3>Description</h3> | ||
<p>some text</p> | ||
<button class="button button--secondary" ng-click="projectCtrl.currentTab = 'instructions'">Instructions</button> | ||
<button class="button button--secondary" ng-click="projectCtrl.currentTab = 'instructions'"> | ||
Instructions | ||
</button> | ||
</div> | ||
<div ng-show="projectCtrl.currentTab === 'instructions'"> | ||
<h3>Instructions</h3> | ||
<button class="button button--secondary" ng-click="projectCtrl.currentTab = 'mapping'">Mapping</button> | ||
<button class="button button--secondary" ng-click="projectCtrl.currentTab = 'mapping'">Mapping | ||
</button> | ||
</div> | ||
<div ng-show="projectCtrl.currentTab === 'mapping'"> | ||
<h3>*Mapping*</h3> | ||
<button class="button button--secondary">Start Mapping</button> | ||
<div ng-show="projectCtrl.mappingStep === 'select'"> | ||
<h3>Choose a task</h3> | ||
<p>There are 2 options for choosing a task:</p> | ||
<p><strong>Option 1: </strong>Select a task by clicking on the map</p> | ||
<p><strong>Option 2: </strong>Select a random task | ||
<button ng-click="projectCtrl.selectRandomTask()" class="button button--secondary"> | ||
Select random | ||
</button> | ||
</p> | ||
</div> | ||
<div ng-show="projectCtrl.mappingStep === 'view'"> | ||
<h3>Task Status: <strong>{{ projectCtrl.selectedTask.get('taskStatus') }}</strong></h3> | ||
|
||
<div ng-show="projectCtrl.isSelectTaskMappable" class="alert alert--success" role="alert"> | ||
<p>This task is available for mapping.</p> | ||
</div> | ||
|
||
<div ng-hide="projectCtrl.isSelectTaskMappable" class="alert alert--danger" role="alert"> | ||
<p>The selected task is not available for mapping.</p> | ||
</div> | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tidy up whitespaces There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
<div> | ||
<button ng-show="projectCtrl.isSelectTaskMappable" class="button button--secondary">Start | ||
Mapping | ||
</button> | ||
<button ng-click="projectCtrl.selectRandomTask()" class="button button--secondary"> | ||
Select another task | ||
</button> | ||
<button class="button button--secondary" ng-click="projectCtrl.clearCurrentSelection()"> | ||
Cancel | ||
</button> | ||
|
||
</div> | ||
<hr/> | ||
<div> | ||
<div> | ||
<h3>Advanced</h3> | ||
<div>Advanced task information and editing options</div> | ||
</div> | ||
<div> | ||
<h5>Details</h5> | ||
<ul> | ||
<li><strong>ID:</strong> #{{ projectCtrl.selectedTask.get('taskId') }}</li> | ||
<li><strong>Status:</strong> {{ projectCtrl.selectedTask.get('taskStatus') }} | ||
</li> | ||
<li><strong>Locked:</strong> {{ projectCtrl.selectedTask.get('taskLocked') }} | ||
</li> | ||
<li><strong>Difficulty:</strong> TODO</li> | ||
<li><strong>Assigned:</strong> TODO</li> | ||
</ul> | ||
<div> | ||
<h5>History</h5> | ||
<ul> | ||
<li>TODO</li> | ||
</ul> | ||
</div> | ||
<div> | ||
<h5>Options</h5> | ||
<label for="form-select-1">Editor</label> | ||
<select class="form__control form__control--small" id="form-select-1"> | ||
<option selected="true">ID Editor</option> | ||
<option>JOSM</option> | ||
<option>Potlach 2</option> | ||
<option>Walking papers</option> | ||
<option>Field papers</option> | ||
</select> | ||
<button class="button button--primary-unbounded">Preview task in OSM ID Editor | ||
</button> | ||
<button class="button button--primary-unbounded">View OSM changesets</button> | ||
<button class="button button--primary-unbounded">View changes in overpass turbo | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
<div ng-show="projectCtrl.mappingStep === 'none-available'"> | ||
<div class="alert alert--danger" role="alert"> | ||
<p>There are no tasks currently available for mapping.</p> | ||
</div> | ||
</div> | ||
|
||
</div> | ||
</div> | ||
<div id="map" class="map-container"></div> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add function comment