Skip to content

Commit 7200aac

Browse files
authored
Merge pull request #208 from mapswipe/dev
Generate Stats, Create Projects, Geometry Validation
2 parents f4babb7 + 373eb9f commit 7200aac

File tree

13 files changed

+1099
-187
lines changed

13 files changed

+1099
-187
lines changed

docker-compose.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ services:
5353
context: mapswipe_workers/
5454
depends_on:
5555
- postgres
56-
command: mapswipe_workers --verbose run --schedule m
56+
command: mapswipe_workers --verbose run --schedule m --only_new_results
5757
volumes:
5858
- ./api-data:/var/lib/mapswipe_workers/api-data/:rw
5959
- ./api-data/agg_res_by_task_id:/var/lib/mapswipe_workers/api-data/agg_res_by_task_id:rw

manager_dashboard/manager_dashboard/create.html

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,16 @@
2222
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
2323
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
2424
<link type="text/css" rel="stylesheet" href="css/mapswipe.css" />
25+
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
26+
integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
27+
crossorigin=""/>
28+
<!-- Make sure you put this AFTER Leaflet's CSS -->
29+
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"
30+
integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og=="
31+
crossorigin=""></script>
32+
<script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>
2533
</head>
26-
<body>
34+
<body onload="initMap()">
2735

2836
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
2937
<a class="navbar-brand" href="index.html">
@@ -74,10 +82,30 @@ <h3>Basic Project Information</h3>
7482

7583
<form class="form-style-7">
7684
<ul>
85+
<li>
86+
<label for="projectTopic">Project Topic</label>
87+
<input type="text" name="projectTopic" id="projectTopic" maxlength="50" required>
88+
<span>Enter the topic of your project (50 chars max).</span>
89+
</li>
90+
<li>
91+
<label for="projectRegion">Project Region</label>
92+
<input type="text" name="projectRegion" id="projectRegion" maxlength="50" required>
93+
<span>Enter name of your project Region (50 chars max).</span>
94+
</li>
95+
<li>
96+
<label for="projectNumber">Project Number</label>
97+
<input type="number" name="projectNumber" id="projectNumber" min="1" value="1">
98+
<span>Is this project part of a bigger campaign with multiple projects?</span>
99+
</li>
100+
<li>
101+
<label for="requestingOrganisation">Requesting Organisation</label>
102+
<input type="text" name="requestingOrganisation" id="requestingOrganisation" maxlength="100" required>
103+
<span>Which group, institution or community is requesting this project.</span>
104+
</li>
77105
<li>
78106
<label for="name">Name</label>
79-
<input type="text" name="name" id="name" maxlength="25" required>
80-
<span>Enter the name of your project (25 chars max).</span>
107+
<p id="name"></br>[projectTopic] - [projectRegion](taskNumber)<br>[requesting organisation]</p>
108+
<span>We will generate you project name based on your inputs above.</span>
81109
</li>
82110
<li>
83111
<label for="lookFor">Look For</label>
@@ -113,7 +141,7 @@ <h3>Basic Project Information</h3>
113141
</li>
114142
<li>
115143
<label for="groupSize">Group Size</label>
116-
<input type="number" name="groupSize" id="groupSize" value="50" min="10" max="200">
144+
<input type="number" name="groupSize" id="groupSize" value="120" min="10" max="200">
117145
<span>How big should a mapping session be? Group size refers to the number of tasks per mapping session.</span>
118146
</li>
119147
<li></li>
@@ -136,6 +164,8 @@ <h3>Project Type Specific Information</h3>
136164
<label for="geometry">GeoJSON File</label>
137165
<!-- <textarea name="geometry" id="geometry" onkeyup="adjust_textarea(this)"></textarea> -->
138166
<input type="file" accept=".GeoJSON" id="geometry" onchange='openFile(event)'>
167+
<div id="geometryMap"></div>
168+
<p id="geometryInfo"></p>
139169
<p id="geometryContent"></p>
140170
<span>Upload your project area as GeoJSON File. Make sure that you provide a single polygon geometry.</span>
141171
</li>
@@ -161,7 +191,7 @@ <h3>Project Type Specific Information</h3>
161191
</li>
162192
<li id="tileServerCreditsFieldBuildArea">
163193
<label for="tileServerCreditsFieldBuildArea">Imagery Credits</label>
164-
<input type="text" name="tileServerCreditsBuildArea" id="tileServerCreditsBuildArea">
194+
<input type="text" name="tileServerCreditsBuildArea" id="tileServerCreditsBuildArea" value="© 2019 Microsoft Corporation, Earthstar Geographics SIO">
165195
<span>Insert appropriate imagery credits. E.g. for Bing: "© 2019 Microsoft Corporation, Earthstar Geographics SIO"</span>
166196
</li>
167197
<li>
@@ -209,7 +239,7 @@ <h3>Project Type Specific Information</h3>
209239
</li>
210240
<li id="tileServerCreditsFieldFootprint">
211241
<label for="tileServerCreditsFieldFootprint">Imagery Credits</label>
212-
<input type="text" name="tileServerCreditsFootprint" id="tileServerCreditsFootprint">
242+
<input type="text" name="tileServerCreditsFootprint" id="tileServerCreditsFootprint" value="© 2019 Microsoft Corporation, Earthstar Geographics SIO">
213243
<span>Insert appropriate imagery credits. E.g. for Bing: "© 2019 Microsoft Corporation, Earthstar Geographics SIO"</span>
214244
</li>
215245
<li>
@@ -229,6 +259,8 @@ <h3>Project Type Specific Information</h3>
229259
<label for="geometry">GeoJSON File</label>
230260
<!-- <textarea name="geometry" id="geometry" onkeyup="adjust_textarea(this)"></textarea> -->
231261
<input type="file" accept=".GeoJSON" id="geometryChangeDetection" onchange='openFile(event)'>
262+
<div id="geometryChangeDetectionMap"></div>
263+
<p id="geometryChangeDetectionInfo"></p>
232264
<p id="geometryChangeDetectionContent"></p>
233265
<span>Upload your project area as GeoJSON File. Make sure that you provide a single polygon geometry.</span>
234266
</li>

manager_dashboard/manager_dashboard/css/mapswipe.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,6 @@
132132
background: #6B9FFF;
133133
color:#fff;
134134
}
135+
136+
#geometryMap { height: 300px; width: 100%}
137+
#geometryChangeDetectionMap { height: 300px; width: 100%}

manager_dashboard/manager_dashboard/js/forms.js

Lines changed: 95 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ function displayProjectTypeFormular(projectType) {
1111
document.getElementById("ChangeDetectionProjectFormular").style.display = "None";
1212
document.getElementById("tileServerBuildArea").value = "bing";
1313
displayTileServer ("bing", "BuildArea", "");
14+
setTimeout(function(){ BuildAreaMap.invalidateSize()}, 400);
1415
} else if (projectType == 2) {
1516
document.getElementById("FootprintProjectFormular").style.display = "block";
1617
document.getElementById("BuildAreaProjectFormular").style.display = "None";
@@ -25,6 +26,7 @@ function displayProjectTypeFormular(projectType) {
2526
document.getElementById("tileServerChangeDetectionB").value = "bing";
2627
displayTileServer ("bing", "ChangeDetectionA", "");
2728
displayTileServer ("bing", "ChangeDetectionB", "");
29+
setTimeout(function(){ ChangeDetectionMap.invalidateSize()}, 400);
2830
}
2931
}
3032

@@ -47,11 +49,14 @@ function clear_all_fields() {
4749
for (i = 0; i < forms.length; i++) {
4850
forms[i].reset()
4951
}
52+
document.getElementById('geometryInfo').innerHTML = ''
5053
document.getElementById('geometryContent').innerHTML = ''
54+
BuildAreaLayer.clearLayers()
55+
document.getElementById('geometryChangeDetectionInfo').innerHTML = ''
5156
document.getElementById('geometryChangeDetectionContent').innerHTML = ''
57+
ChangeDetectionLayer.clearLayers()
5258
document.getElementById('imageText').innerHTML = ''
5359
document.getElementById('imageFile').src = ''
54-
5560
displayProjectTypeFormular(1)
5661
}
5762

@@ -66,20 +71,84 @@ function displayImportForm() {
6671

6772
function openFile(event) {
6873
var input = event.target;
69-
element_id = event.target.id + 'Content'
74+
var info_element_id = event.target.id + 'Info'
75+
var content_element_id = event.target.id + 'Content'
76+
var map_element_id = event.target.id + 'Map'
77+
78+
var info_output = document.getElementById(info_element_id);
79+
info_output.innerHTML = '';
80+
info_output.style.display = 'block'
81+
82+
var content_output = document.getElementById(content_element_id);
83+
84+
if (event.target.id === 'geometry') {
85+
var map = BuildAreaMap
86+
var layer = BuildAreaLayer
87+
var zoomLevel = parseInt(document.getElementById('zoomLevel').value)
88+
} else {
89+
var map = ChangeDetectionMap
90+
var layer = ChangeDetectionLayer
91+
var zoomLevel = parseInt(document.getElementById('zoomLevelChangeDetection').value)
92+
}
7093

7194
var reader = new FileReader();
7295
reader.onload = function(){
7396

7497
try {
7598
var text = reader.result;
76-
var geometry = JSON.parse(text)
77-
var output = document.getElementById(element_id);
78-
output.innerHTML = text;
99+
var geojsonData = JSON.parse(text)
100+
101+
// check number of features
102+
numberOfFeatures = geojsonData['features'].length
103+
console.log('number of features: ' + numberOfFeatures)
104+
if (numberOfFeatures > 1) {
105+
throw 'too many features: ' + numberOfFeatures
106+
}
107+
info_output.innerHTML += 'Number of Features: ' + numberOfFeatures + '<br>';
108+
info_output.style.display = 'block'
109+
110+
// check input geometry type
111+
feature = geojsonData['features'][0]
112+
type = turf.getType(feature)
113+
console.log('geometry type: ' + type)
114+
if (type !== 'Polygon' & type !== 'MultiPolygon') {
115+
throw 'wrong geometry type: ' + type
116+
}
117+
info_output.innerHTML += 'Feature Type: ' + type + '<br>';
118+
info_output.style.display = 'block'
119+
120+
// check project size
121+
122+
area = turf.area(feature)/1000000 // area in square kilometers
123+
maxArea = (20 - zoomLevel) * (20 - zoomLevel) * 1250
124+
console.log('project size: ' + area + ' sqkm')
125+
if (area > 5000) {
126+
throw 'project is to large: ' + area + ' sqkm; ' + 'max allowed size for this zoom level: ' + maxArea + ' sqkm'
127+
}
128+
info_output.innerHTML += 'Project Size: ' + area + ' sqkm<br>';
129+
info_output.style.display = 'block'
130+
131+
// add feature to map
132+
layer.clearLayers()
133+
layer.addData(geojsonData);
134+
map.fitBounds(layer.getBounds());
135+
console.log('added input geojson feature')
136+
137+
// add text to html object
138+
info_output.innerHTML += 'Project seems to be valid :)';
139+
info_output.style.display = 'block'
140+
141+
if (event.target.id === 'geometry') {
142+
BuildAreaGeometry = text
143+
} else {
144+
ChangeDetectionGeometry = text
145+
}
146+
147+
79148
}
80149
catch(err) {
81-
var output = document.getElementById(element_id);
82-
output.innerHTML = '<b>Error reading GeoJSON file</b><br>' + err;
150+
info_output.innerHTML = '<b>Error reading GeoJSON file</b><br>' + err;
151+
info_output.style.display = 'block'
83152
}
84153
};
85154
reader.readAsText(input.files[0]);
@@ -105,3 +174,22 @@ function openImageFile(event) {
105174
reader.readAsDataURL(input.files[0]);
106175
};
107176

177+
function initMap() {
178+
BuildAreaMap = L.map('geometryMap').setView([0.0, 0.0], 4);
179+
L.tileLayer( 'https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png', {
180+
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
181+
subdomains: ['a','b','c']
182+
}).addTo( BuildAreaMap );
183+
console.log('added map');
184+
BuildAreaLayer = L.geoJSON().addTo(BuildAreaMap);
185+
setTimeout(function(){ BuildAreaMap.invalidateSize()}, 400);
186+
187+
ChangeDetectionMap = L.map('geometryChangeDetectionMap').setView([0.0, 0.0], 4);
188+
L.tileLayer( 'https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png', {
189+
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
190+
subdomains: ['a','b','c']
191+
}).addTo( ChangeDetectionMap );
192+
console.log('added map');
193+
ChangeDetectionLayer = L.geoJSON().addTo(ChangeDetectionMap);
194+
setTimeout(function(){ ChangeDetectionMap.invalidateSize()}, 400);
195+
}

manager_dashboard/manager_dashboard/js/uploadProjects.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,13 @@ function submitInfo() {
4444
} else {
4545

4646
// get basic project information
47-
var name = document.getElementById("name").value;
47+
var projectTopic = document.getElementById("projectTopic").value;
48+
var projectRegion = document.getElementById("projectRegion").value;
49+
var projectNumber = document.getElementById("projectNumber").value;
50+
var requestingOrganisation = document.getElementById("requestingOrganisation").value;
51+
var name = projectTopic + ' - ' + projectRegion + ' (' + projectNumber + ')\n' + requestingOrganisation
52+
53+
4854
var lookFor = document.getElementById("lookFor").value;
4955
var projectDetails = document.getElementById("projectDetails").value;
5056
var projectType = document.getElementById("projectType").value;
@@ -56,7 +62,7 @@ function submitInfo() {
5662
if (projectType == 1) {
5763

5864
var zoomLevel = document.getElementById("zoomLevel").value;
59-
var geometry = document.getElementById("geometryContent").innerHTML;
65+
var geometry = BuildAreaGeometry;
6066
var tileServer = {
6167
name: document.getElementById("tileServerBuildArea").value,
6268
url: document.getElementById("tileServerUrlBuildArea").value,
@@ -66,6 +72,10 @@ function submitInfo() {
6672

6773
var mapswipe_import = {
6874
name: name,
75+
projectRegion: projectRegion,
76+
projectTopic: projectTopic,
77+
projectNumber: projectNumber,
78+
requestingOrganisation: requestingOrganisation,
6979
lookFor: lookFor,
7080
projectDetails: projectDetails,
7181
projectType: parseInt(projectType),
@@ -107,7 +117,7 @@ function submitInfo() {
107117
} else if (projectType == 3) {
108118

109119
var zoomLevel = document.getElementById("zoomLevelChangeDetection").value;
110-
var geometry = document.getElementById("geometryChangeDetectionContent").innerHTML;
120+
var geometry = ChangeDetectionGeometry;
111121
var tileServerA = {
112122
name: document.getElementById("tileServerChangeDetectionA").value,
113123
url: document.getElementById("tileServerUrlChangeDetectionA").value,

mapswipe_workers/mapswipe_workers/base/base_project.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ def __init__(self, project_draft):
6767
self.projectType = int(project_draft['projectType'])
6868
self.verificationNumber = project_draft['verificationNumber']
6969
self.status = 'new'
70+
self.projectTopic = project_draft.get('projectTopic', None)
71+
self.projectRegion = project_draft.get('projectRegion', None)
72+
self.projectNumber = project_draft.get('projectNumber', None)
73+
self.requestingOrganisation = project_draft.get('requestingOrganisation', None)
7074

7175
# TODO: Implement resultRequiredCounter as property.
7276
# Does not work because for some reason project['group'] = vars()

0 commit comments

Comments
 (0)