2023-10-06 03:34:26 +02:00
import Constants from "../Models/Constants"
2024-12-11 22:41:33 +01:00
import { SpecialVisualizationState } from "../UI/SpecialVisualization"
2025-06-29 22:42:28 +02:00
import { ServerSourceInfo } from "../Models/SourceOverview"
2024-12-11 22:41:33 +01:00
2024-05-13 18:45:43 +02:00
export interface MaprouletteTask {
2024-06-16 16:06:26 +02:00
name : string
description : string
2024-05-13 18:45:43 +02:00
instruction : string
}
2024-12-17 04:23:24 +01:00
export const maprouletteStatus = [
"Open" ,
2024-12-17 03:31:28 +01:00
"Fixed" ,
"False_positive" ,
"Skipped" ,
"Deleted" ,
"Already fixed" ,
"Too_Hard" ,
"Disabled" ,
] as const
2024-12-17 04:23:24 +01:00
export type MaprouletteStatus = ( typeof maprouletteStatus ) [ number ]
2024-12-11 22:41:33 +01:00
2022-07-13 08:03:09 +00:00
export default class Maproulette {
2023-10-06 03:34:26 +02:00
public static readonly defaultEndpoint = "https://maproulette.org/api/v2"
2025-06-29 22:42:28 +02:00
public static readonly defaultEndpointInfo : ServerSourceInfo = {
url : Maproulette.defaultEndpoint ,
trigger : [ "specific_theme" ] ,
category : "feature" ,
2025-07-10 18:26:31 +02:00
description :
"[MapRoulette](https://wiki.openstreetmap.org/wiki/MapRoulette) is a platform where tasks can be submitted, where every task contains some data about something that should be improved in OpenStreetMap. The intent is that those 'tasks' are solved by the community, effectively working as big, shared 'todo'-list. MapComplete can display such tasks and mark them solved. This is most often done to run an import of data." ,
2025-06-29 22:42:28 +02:00
openData : true ,
sourceAvailable : true ,
2025-07-10 18:26:31 +02:00
selfhostable : true ,
2025-06-29 22:42:28 +02:00
}
2023-10-06 03:34:26 +02:00
public static readonly STATUS_OPEN = 0
public static readonly STATUS_FIXED = 1
public static readonly STATUS_FALSE_POSITIVE = 2
public static readonly STATUS_SKIPPED = 3
public static readonly STATUS_DELETED = 4
public static readonly STATUS_ALREADY_FIXED = 5
public static readonly STATUS_TOO_HARD = 6
public static readonly STATUS_DISABLED = 9
2023-02-14 00:09:04 +01:00
2023-10-06 03:34:26 +02:00
public static singleton = new Maproulette ( )
2023-02-14 00:09:04 +01:00
/ *
2022-07-13 08:03:09 +00:00
* The API endpoint to use
* /
2023-10-06 03:34:26 +02:00
endpoint : string
2022-07-13 08:03:09 +00:00
/ * *
* The API key to use for all requests
* /
2023-10-06 03:34:26 +02:00
private readonly apiKey : string
2022-07-13 08:03:09 +00:00
/ * *
* Creates a new Maproulette instance
* @param endpoint The API endpoint to use
* /
2023-10-05 22:40:57 +02:00
constructor ( endpoint? : string ) {
2023-10-06 03:34:26 +02:00
this . endpoint = endpoint ? ? Maproulette . defaultEndpoint
if ( ! this . endpoint ) {
2023-10-05 22:40:57 +02:00
throw "MapRoulette endpoint is undefined. Make sure that `Maproulette.defaultEndpoint` is defined on top of the class"
}
2023-10-06 03:34:26 +02:00
this . apiKey = Constants . MaprouletteApiKey
2023-10-05 22:40:57 +02:00
}
/ * *
* Converts a status text into the corresponding number
*
* Maproulette . codeToIndex ( "Created" ) // => 0
* Maproulette . codeToIndex ( "qdsf" ) // => undefined
*
* /
public static codeToIndex ( code : string ) : number | undefined {
if ( code === "Created" ) {
2023-10-06 03:34:26 +02:00
return Maproulette . STATUS_OPEN
2023-10-05 22:40:57 +02:00
}
2024-12-17 04:39:38 +01:00
const i = maprouletteStatus . indexOf ( < any > code )
2024-12-17 04:23:24 +01:00
if ( i < 0 ) {
2024-12-17 03:31:28 +01:00
return undefined
2023-10-05 22:40:57 +02:00
}
2024-12-17 03:31:28 +01:00
return i
2022-07-13 08:03:09 +00:00
}
/ * *
2023-02-14 00:09:04 +01:00
* Close a task ; might throw an error
*
* Also see :https : //maproulette.org/docs/swagger-ui/index.html?url=/assets/swagger.json&docExpansion=none#/Task/setTaskStatus
2022-07-13 08:03:09 +00:00
* @param taskId The task to close
2023-02-14 00:09:04 +01:00
* @param status A number indicating the status . Use MapRoulette . STATUS_ *
* @param options Additional settings to pass . Refer to the API - docs for more information
2022-07-13 08:03:09 +00:00
* /
2023-02-14 00:09:04 +01:00
async closeTask (
taskId : number ,
status = Maproulette . STATUS_FIXED ,
2024-12-11 22:41:33 +01:00
state : SpecialVisualizationState ,
2023-02-14 00:09:04 +01:00
options ? : {
comment? : string
tags? : string
requestReview? : boolean
completionResponses? : Record < string , string >
2024-12-17 04:23:24 +01:00
}
2023-02-14 00:09:04 +01:00
) : Promise < void > {
2023-10-06 03:34:26 +02:00
console . log ( "Maproulette: setting" , ` ${ this . endpoint } /task/ ${ taskId } / ${ status } ` , options )
2024-12-11 22:41:33 +01:00
options ? ? = { }
const userdetails = state . osmConnection . userDetails . data
options . tags = ` MapComplete MapComplete: ${ state . theme . id } ; userid: ${ userdetails ? . uid } ; username: ${ userdetails ? . name } `
2023-02-14 00:09:04 +01:00
const response = await fetch ( ` ${ this . endpoint } /task/ ${ taskId } / ${ status } ` , {
2022-07-13 08:03:09 +00:00
method : "PUT" ,
headers : {
"Content-Type" : "application/json" ,
2024-12-17 03:31:28 +01:00
apiKey : this.apiKey ,
2022-07-13 08:03:09 +00:00
} ,
2024-12-17 03:31:28 +01:00
body : JSON.stringify ( options ) ,
2023-10-06 03:34:26 +02:00
} )
2023-02-14 00:09:04 +01:00
if ( response . status !== 204 ) {
2023-10-06 03:34:26 +02:00
console . log ( ` Failed to close task: ${ response . status } ` )
throw ` Failed to close task: ${ response . status } `
2023-06-09 16:13:35 +02:00
}
}
2022-07-13 08:03:09 +00:00
}