Navigation Menu

Skip to content

Creating Quick Fix Challenges

Neil Rotstan edited this page May 7, 2020 · 6 revisions

⚠️ Quick Fix challenges are deprecated. Use Cooperative Challenges instead

MapRoulette v3.6 replaced the entire suggested-fix concept with a new mechanism called Cooperative Challenges that allow uncommitted, in-progress work to be handed off to mappers for completion or verification. Cooperative Challenges are much more flexible and support nearly any kind of edit. The old idea of "quick fix" challenges are still possible with a new Tag Fix variant of cooperative challenges. Learn more on the Cooperative Challenges wiki page.

Quick fix challenges -- documented below -- can still be created in v3.6, but are now considered deprecated. Existing quick-fix challenges will continue to work for the forseeable future, but the ability to create new ones will be discontinued in a future release.


Introduction

MapRoulette version 3.4 introduced support for "quick-fix" (a.k.a. suggested-fix) challenges in which proposed changes to OSM data are included with each task, allowing the mapper to simply review the suggested change against current OSM data and either approve or reject it -- no editor needed. Approved changes are immediately submitted as an OSM changeset by MapRoulette on behalf of the mapper.

Note: Only tag changes (additions, modifications, removals) are supported by quick-fixes at this time. Support for geometry changes will be incrementally added in future releases.

Quick-fix challenges can be created through the API or by adding a special property to task features in your GeoJSON file that describes the OSM data modifications to perform.

Quick-Fix GeoJSON Structure

All tasks in a quick-fix challenge must contain a suggested fix that is to be proposed to the user. The suggested fix for a task feature is added under a maproulette property on the feature and contains both a meta section with information about the fix (such as a format version so that the data format can be updated over time while supporting older formats) and an operations section that lists the data-manipulation operations to be performed.

Here is an example that proposes to modify a Way by setting its foo tag to the value bar. The complete GeoJSON feature is included for context. Note the maproulette property field, with the nested suggestedFix object describing the proposed change.

{
  "type": "Feature",
  "properties": {
    "building": "yes",
    "@id": "way/243499890",
    "maproulette": {                              <---- special maproulette property 
      "suggestedFix": {                           <---- suggested fix 
        "meta": {                                 <---- meta section 
          "version": 1
        },
        "operations": [                           <---- operations section 
          {
            "operationType": "modifyElement",     <---- independent operation 
            "data": {
              "id": "way/243499890",
              "operations": [
                {
                  "operation": "setTags",         <---- dependent operation 
                  "data": {
                    "foo": "bar"
                  }
                }
              ]
            }
          }
        ]
      }
    }
  },
  "geometry": {
    "type": "Polygon",
    "coordinates": [
      [
        [
          -120.1870532,
          48.4797882
        ],
        [
          -120.1868818,
          48.4797712
        ],
        [
          -120.1868969,
          48.4797045
        ],
        [
          -120.1870683,
          48.4797215
        ],
        [
          -120.1870532,
          48.4797882
        ]
      ]
    ]
  }
}

A suggested fix consists of one or more independent (or parent) operations which may include embedded dependent (or child) operations. An example of an independent operation would be modifyElement. Examples of dependent operations, which manipulate the target of their parent independent operation, would be setTags and unsetTags. The data structure representing an operation is intended to be generic in nature and consists simply of an operation field identifying the type of operation and an optional data payload specific to that operation.

Unlike an OSM changeset, which often requires a complete snapshot of the element data to be provided, a suggested fix is intended to capture only the actual changes required to complete the task.

Operations Reference

This is a brief reference of operations. Note that support is limited in current versions of MapRoulette and, for illustrative purposes, examples may contain proposed or as-of-yet unimplemented operations that may be subject to change or forgone entirely.

Independent Operations

  • createElement under development
  • modifyElement supported in v3.4
  • deleteElement not yet supported

Dependent Operations

  • setFields not yet supported
  • setTags supported in v3.4
  • unsetTags supported in v3.4
  • exclusiveChoice under development
  • replaceMembers not yet supported
  • appendMembers not yet supported
  • prependMembers not yet supported

Independent Operations

Note: Any OSM ids referenced in an operation must be of the form of elementType/numericId, e.g. node/123456789. New elements that have not yet been added to OSM should use (and be referenced by) negative numeric ids unique within the suggested fix, e.g. way/-1

createElement

Creates a new OSM element (node, way, or relation). data should consist of an id and optional fields, tags, and members objects to flesh out element data.

Example:

{
  "operation": "createElement"
  "data": {
    "id": "node/-1",
    "fields": {
      "lat": "48.4768875",
      "lon": "-120.1883757"
    },
    "tags": {
      "amenity": "bench",
      "backrest": "yes"
    }
  }
}

Status: limited support under development

modifyElement

Updates an existing OSM element with a series of dependent operations on fields, tags, and/or members that will be applied in the order they appear. data should consist of an id and operations array with dependent operations to be performed.

Example:

{
  "operation": "modifyElement"
  "data": {
    "id": "way/12345678",
    "operations": [{
      "operation": "setTags",
      "data": {
        "building": "yes",
      }
    }, {
      "operation": "setMembers",
      "data": [
        "node/24681012",
        "node/35791113",
        "node/10152025",
        "node/91827364",
        "node/24681012",
      ]
    }]
  }
}

Status: supported as of MapRoulette v3.4

deleteElement

Delete an OSM element

Example:

{
  "operation": "deleteElement"
  "data": {
    "id": "node/12345678"
  }
}

Status: not yet supported

Dependent Operations

setTags

Sets the value of one or more tags on the enclosing OSM element. This operation will add the tag if it does not yet exist on the element, or update the value of an existing tag if it does. data should be an object with tag names as keys.

Example:

{
  "operation": "setTags",
  "data": {
    "name": "Walgreens",
    "amenity": "pharmacy"
  }
}

Status: supported as of MapRoulette v3.4

unsetTags

Removes one or more tags from the enclosing OSM element. This operation will delete the tag from the OSM element if it exists, or silently do nothing if it does not. data should be an array of tag names to remove.

Example:

{
  "operation": "unsetTags",
  "data": ["sometag", "anothertag"]
}

Status: supported as of MapRoulette v3.4

exclusiveChoice

Associates sets of dependent operations with mutually exclusive choices. The choices will be presented to the mapper and operations associated with the selected choice will be applied. Only one choice can be selected.

data should be an array of two or more choices, each of which is an object that should contain a label field and an operations field. label should be a short string identifying the choice to mappers (or an object if multiple translations are to be provided -- see section below). operations should be an array of one or more dependent operations that are to be applied should that choice be selected.

Note: MapRoulette provides a mechanism for mappers to indicate that none of the choices are appropriate; it is not necessary for you to offer an extra choice for that scenario

Example:

{
  "operation": "exlusiveChoice",
  "data": [{
    "label": "Paved road",
    "operations": [{
      "operation": "setTags",
      "data": {
        "surface": "paved",
      }
    }],
  }, {
    "label": "Unpaved road",
    "operations": [{
      "operation": "setTags",
      "data": {
        "surface": "unpaved",
      }
    }],
  }]
}

Labels in Multiple Languages:

Labels for the choices can optionally be provided in multiple languages. Instead of setting label to a string, set it to an object with a default field for the default label (shown if no translations match the user's locale) along with desired translations keyed by their respective ISO 639-1 alpha-2 code (second column). For example:

"label": {
  "default": "Paved road",
  "es": "camino pavimentado",
  "fr": "rue pavée"
}

In the above example, an en could also have been provided (duplicating the default entry), but it's not necessary since the default will be shown to any users who do not use es or fr locales.

Note: simply setting label to a string is equivalent to setting it to an object containing only a default entry

Status: under development