Skip to content

Commit 514ccb8

Browse files
authored
Merge pull request #1006 from mapswipe/feature/manager-dashboard/street-tutorial
Feature/manager dashboard/street tutorial
2 parents 65555a8 + c27e228 commit 514ccb8

File tree

6 files changed

+171
-18
lines changed

6 files changed

+171
-18
lines changed

manager-dashboard/app/views/NewProject/utils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,8 @@ export const projectFormSchema: ProjectFormSchema = {
324324
['projectType'],
325325
['customOptions'],
326326
(formValues) => {
327-
if (formValues?.projectType === PROJECT_TYPE_FOOTPRINT) {
327+
if (formValues?.projectType === PROJECT_TYPE_FOOTPRINT
328+
|| formValues?.projectType === PROJECT_TYPE_STREET) {
328329
return {
329330
customOptions: {
330331
keySelector: (key) => key.value,

manager-dashboard/app/views/NewTutorial/ScenarioPageInput/index.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
PROJECT_TYPE_FOOTPRINT,
1818
PROJECT_TYPE_CHANGE_DETECTION,
1919
PROJECT_TYPE_COMPLETENESS,
20+
PROJECT_TYPE_STREET,
2021
} from '#utils/common';
2122
import TextInput from '#components/TextInput';
2223
import Heading from '#components/Heading';
@@ -318,7 +319,14 @@ export default function ScenarioPageInput(props: Props) {
318319
lookFor={lookFor}
319320
/>
320321
)}
321-
{(projectType && projectType !== PROJECT_TYPE_FOOTPRINT) && (
322+
{projectType === PROJECT_TYPE_STREET && (
323+
<div>
324+
Preview not available.
325+
</div>
326+
)}
327+
{(projectType
328+
&& projectType !== PROJECT_TYPE_FOOTPRINT
329+
&& projectType !== PROJECT_TYPE_STREET) && (
322330
<SegmentInput
323331
name={undefined}
324332
value={activeSegmentInput}

manager-dashboard/app/views/NewTutorial/index.tsx

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,15 @@ import {
6969
PROJECT_TYPE_COMPLETENESS,
7070
PROJECT_TYPE_CHANGE_DETECTION,
7171
PROJECT_TYPE_FOOTPRINT,
72+
PROJECT_TYPE_STREET,
7273
ProjectType,
7374
projectTypeLabelMap,
7475
} from '#utils/common';
7576

7677
import {
7778
tileServerUrls,
7879
tutorialFormSchema,
79-
defaultFootprintCustomOptions,
80+
getDefaultOptions,
8081
TutorialFormType,
8182
PartialTutorialFormType,
8283
PartialInformationPagesType,
@@ -189,6 +190,11 @@ function getGeoJSONError(
189190
tile_y: 'number',
190191
tile_z: 'number',
191192
},
193+
[PROJECT_TYPE_STREET]: {
194+
id: ['string', 'number'],
195+
reference: 'number',
196+
screen: 'number',
197+
},
192198
};
193199
const schemaErrors = tutorialTasks.features.map(
194200
(feature) => checkSchema(
@@ -341,7 +347,6 @@ const defaultTutorialFormValue: PartialTutorialFormType = {
341347
name: TILE_SERVER_ESRI,
342348
credits: tileServerDefaultCredits[TILE_SERVER_ESRI],
343349
},
344-
customOptions: defaultFootprintCustomOptions,
345350
};
346351

347352
type SubmissionStatus = 'started' | 'imageUpload' | 'tutorialSubmit' | 'success' | 'failed';
@@ -646,6 +651,11 @@ function NewTutorial(props: Props) {
646651
|| tutorialSubmissionStatus === 'tutorialSubmit'
647652
);
648653

654+
const tileServerVisible = value.projectType === PROJECT_TYPE_BUILD_AREA
655+
|| value.projectType === PROJECT_TYPE_FOOTPRINT
656+
|| value.projectType === PROJECT_TYPE_COMPLETENESS
657+
|| value.projectType === PROJECT_TYPE_CHANGE_DETECTION;
658+
649659
const tileServerBVisible = value.projectType === PROJECT_TYPE_CHANGE_DETECTION
650660
|| value.projectType === PROJECT_TYPE_COMPLETENESS;
651661

@@ -716,6 +726,7 @@ function NewTutorial(props: Props) {
716726
setFieldValue(undefined, 'tutorialTasks');
717727
setFieldValue(undefined, 'scenarioPages');
718728
setFieldValue(newValue, 'projectType');
729+
setFieldValue(getDefaultOptions(newValue), 'customOptions');
719730
},
720731
[setFieldValue],
721732
);
@@ -761,7 +772,10 @@ function NewTutorial(props: Props) {
761772
autoFocus
762773
/>
763774
</InputSection>
764-
{value.projectType === PROJECT_TYPE_FOOTPRINT && (
775+
{(
776+
value.projectType === PROJECT_TYPE_FOOTPRINT
777+
|| value.projectType === PROJECT_TYPE_STREET
778+
) && (
765779
<InputSection
766780
heading="Custom Options"
767781
actions={(
@@ -896,17 +910,20 @@ function NewTutorial(props: Props) {
896910
)}
897911
</div>
898912
</InputSection>
899-
<InputSection
900-
heading={tileServerBVisible ? 'Tile Server A' : 'Tile Server'}
901-
>
902-
<TileServerInput
903-
name={'tileServer' as const}
904-
value={value.tileServer}
905-
error={error?.tileServer}
906-
onChange={setFieldValue}
907-
disabled={submissionPending || projectTypeEmpty}
908-
/>
909-
</InputSection>
913+
{tileServerVisible && (
914+
<InputSection
915+
heading={tileServerBVisible ? 'Tile Server A' : 'Tile Server'}
916+
>
917+
<TileServerInput
918+
name={'tileServer' as const}
919+
value={value.tileServer}
920+
error={error?.tileServer}
921+
onChange={setFieldValue}
922+
disabled={submissionPending || projectTypeEmpty}
923+
/>
924+
</InputSection>
925+
)}
926+
910927
{tileServerBVisible && (
911928
<InputSection
912929
heading="Tile Server B"

manager-dashboard/app/views/NewTutorial/utils.ts

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
PROJECT_TYPE_CHANGE_DETECTION,
2727
PROJECT_TYPE_COMPLETENESS,
2828
PROJECT_TYPE_FOOTPRINT,
29+
PROJECT_TYPE_STREET,
2930
IconKey,
3031
} from '#utils/common';
3132

@@ -257,6 +258,33 @@ export const defaultFootprintCustomOptions: PartialTutorialFormType['customOptio
257258
},
258259
];
259260

261+
export const defaultStreetCustomOptions: PartialTutorialFormType['customOptions'] = [
262+
{
263+
optionId: 1,
264+
value: 1,
265+
title: 'Yes',
266+
icon: 'checkmark-outline',
267+
iconColor: colorKeyToColorMap.green,
268+
description: 'the object you are looking for is in the image.',
269+
},
270+
{
271+
optionId: 2,
272+
value: 0,
273+
title: 'No',
274+
icon: 'close-outline',
275+
iconColor: colorKeyToColorMap.red,
276+
description: 'the object you are looking for is NOT in the image.',
277+
},
278+
{
279+
optionId: 3,
280+
value: 2,
281+
title: 'Not Sure',
282+
icon: 'remove-outline',
283+
iconColor: colorKeyToColorMap.gray,
284+
description: 'if you\'re not sure or there is bad imagery',
285+
},
286+
];
287+
260288
export function deleteKey<T extends object, K extends keyof T>(
261289
value: T,
262290
key: K,
@@ -268,6 +296,18 @@ export function deleteKey<T extends object, K extends keyof T>(
268296
return copy;
269297
}
270298

299+
export function getDefaultOptions(projectType: ProjectType | undefined) {
300+
if (projectType === PROJECT_TYPE_FOOTPRINT) {
301+
return defaultFootprintCustomOptions;
302+
}
303+
304+
if (projectType === PROJECT_TYPE_STREET) {
305+
return defaultStreetCustomOptions;
306+
}
307+
308+
return undefined;
309+
}
310+
271311
export interface BuildAreaProperties {
272312
reference: number;
273313
screen: number;
@@ -308,6 +348,12 @@ export interface ChangeDetectionProperties {
308348
// taskId: string;
309349
}
310350

351+
export interface StreetProperties {
352+
id: string;
353+
reference: number;
354+
screen: number;
355+
}
356+
311357
export type BuildAreaGeoJSON = GeoJSON.FeatureCollection<
312358
GeoJSON.Geometry,
313359
BuildAreaProperties
@@ -323,9 +369,14 @@ export type ChangeDetectionGeoJSON = GeoJSON.FeatureCollection<
323369
ChangeDetectionProperties
324370
>;
325371

372+
export type StreetGeoJSON = GeoJSON.FeatureCollection<
373+
GeoJSON.Geometry,
374+
StreetProperties
375+
>;
376+
326377
export type TutorialTasksGeoJSON = GeoJSON.FeatureCollection<
327378
GeoJSON.Geometry,
328-
BuildAreaProperties | FootprintProperties | ChangeDetectionProperties
379+
BuildAreaProperties | FootprintProperties | ChangeDetectionProperties | StreetProperties
329380
>;
330381

331382
export type CustomOptions = {
@@ -724,7 +775,8 @@ export const tutorialFormSchema: TutorialFormSchema = {
724775
}),
725776
};
726777

727-
if (formValues?.projectType === PROJECT_TYPE_FOOTPRINT) {
778+
if (formValues?.projectType === PROJECT_TYPE_FOOTPRINT
779+
|| formValues?.projectType === PROJECT_TYPE_STREET) {
728780
return {
729781
customOptions: customOptionField,
730782
};
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Creating a New 'Street' Tutorial
2+
### Useful Links
3+
- MapSwipe Development Server: [https://dev-managers.mapswipe.org]
4+
- MapSwipe Development App Installation Guide: [https://github.com/mapswipe/mapswipe/wiki/How-to-test-the-development-version-of-MapSwipe](https://github.com/mapswipe/mapswipe/wiki/How-to-test-the-development-version-of-MapSwipe)
5+
6+
## Select appropriate Mapillary imagery for the tutorial (with JOSM and Mapillary plug-in)
7+
8+
1. Open JOSM. Make sure the [JOSM Mapillary plug-in](https://wiki.openstreetmap.org/wiki/JOSM/Plugins/Mapillary) is installed
9+
2. **File > Download data**. Select an area in which you expect appropriate example imagery available on Mapillary and **Download**
10+
3. **Imagery > Mapillary** to download sequences and images for the current area
11+
4. If helpful, use the Mapillary filter dialog to filter images (for start and end date, user and/or organization)
12+
5. Click **Mapillary** in Layers controls to select the Mapillary layer
13+
6. Zoom in until you can see images location markers (green dots)
14+
7. Click on the dots to view the images
15+
8. Once you have found an image that you would like to use in your tutorial, **File > Export Mapillary images** and select **Export selected images**
16+
9. Click **Explore**
17+
10. Choose a parent folder for all images in this tutorial
18+
11. **OK**
19+
12. Repeat until you have exported all the images that you would like to use in the tutorial. Use the same parent folder for all images.
20+
21+
## Add exported Mapillary images as geotagged images in QGIS
22+
23+
1. Open QGIS
24+
2. **Processing Toolbox > Vector creation > Import geotagged photos**
25+
3. Select the folder containing all exported Mapillary images and check **Scan recursively**
26+
4. **Run**
27+
5. **Properties > Display** and add `<img src="file:///[% photo %]" width="350" height="250">` to HTML Map Tip to show images on a pop up
28+
6. **View > Show Map Tips**
29+
7. If you keep the mouse tip on the image markers, a pop up with the image will appear
30+
31+
## Edit geotagged images in QGIS
32+
33+
1. Right click on layer.
34+
2. **Properties > Field**
35+
3. **Toggle editing mode**
36+
4. Change the name of the `filename` column to `id`
37+
5. Add `Integer (32 bit)` columns titled `screen` and `reference`.
38+
6. Populate the `reference` and `screen` fields.
39+
* `reference` is the value of the correct answer option for the image.
40+
* `screen` determines the order of the images in the tutorial and should start with `1`.
41+
7. Delete any rows representing images that you do not want to use
42+
43+
## Export as GeoJSON
44+
45+
1. **Toggle editing mode**
46+
2. **Save**
47+
3. Right click, **Export > Save Features As...**
48+
4. Choose Format GeoJSON, CRS EPSG:4326 - WGS 84
49+
5. Select only `id`, `reference` and `screen` as fields to export. Deselect all other fields.
50+
6. Choose a file name and location and click OK to save
51+
52+
## Create tutorial
53+
54+
1. Go to https://dev-managers.mapswipe.org/
55+
2. Select **Projects** and then **Add New Tutorial**.
56+
3. Check that **Project Type** is set to **Street**.
57+
4. Fill in all the fields, following the instructions. Upload your `GeoJSON` you just created with the scenarios where it says **Scenario Pages**.
58+
5. Submit
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"type": "FeatureCollection",
3+
"name": "cobblestone-scenario",
4+
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
5+
"features": [
6+
{
7+
"type": "Feature",
8+
"properties": { "id": "378811598610667", "reference": 1, "screen": 2 },
9+
"geometry": { "type": "Point", "coordinates": [ 13.45285, 52.508467, 0.0 ] }
10+
},
11+
{
12+
"type": "Feature",
13+
"properties": { "id": "1171343450849316", "reference": 0, "screen": 1 },
14+
"geometry": { "type": "Point", "coordinates": [ 13.4514123, 52.5103378, 0.0 ] }
15+
}
16+
]
17+
}

0 commit comments

Comments
 (0)