mapcomplete/Docs/Integrating_Maproulette.md

4.7 KiB

Integrating MapRoulette

MapRoulette is a website which has challenges. A challenge is a collection of microtasks, i.e. mapping tasks which can be solved in a few minutes.

A perfect example of this is to setup such a challenge to e.g. import new points. Important: always follow the import guidelines if you want to import data. (Another approach to set up a guided import is to create a map note for every point with the import helper. This however litters the map and will upset mappers if used with to much points.)

The API

Most of the heavy lifting is done in layer maproulette. Extend this layer with your needs The API is shortly discussed here for future reference only.

There is an API-endpoint at https://maproulette.org/api/v2/tasks/box/{x_min}/{y_min}/{x_max}/{y_max} which can be used to query all tasks in a bbox and returns this as geojson. Hint: use the maproulette theme in debug mode to inspect all properties.

To view the overview a single challenge, visit https://maproulette.org/browse/challenges/<challenge-id> with your browser. The API endpoint for a single challenge is https://maproulette.org/api/v2/challenge/view/<challenge-id> which returns a geojson.

Displaying MapRoulette data in MapComplete

As you'll probably want to link MapComplete to your challenge, reuse maproulette_challenge. It has a basic framework already to load the tags.

Of course, interacting with the tasks is the next step.

Detecting nearby features

You can use calculatedTags to add a small piece of code to e.g. detect nearby entities.

The following example is to match hotels:

    "calculatedTags": [
      "_closest_osm_hotel=feat.closest('hotel')?.properties?.id",
      "_closest_osm_hotel_distance=feat.distanceTo(feat.properties._closest_osm_hotel)",
      "_has_closeby_feature=Number(feat.properties._closest_osm_hotel_distance) < 50 ? 'yes' : 'no'"
    ], 

This can be used to decide if tags should be applied on an existing object or a new point should be created.

Creating a new point based on a maproulette challenge (Guided import)

Requirement: the MapRoulette task should have tags added.

One can add import-button in the featureInfoBox (documentation here). Note that the import button has support for MapRoulette and is able to close the task if the property containing the maproulette-id is given:

{
    "id": "import-button",
    "render": {
      "special": {
        "type": "import_button",
        "targetLayer": "<the layer in which the point should appear afterwards>",
        "tags": "tags", -- should stay 'tags'
        "maproulette_id": "mr_taskId",  -- important to get the task closed
        "text": {
          "en": "Import this point" -- or a nice message
        },
        "icon": "./assets/svg/addSmall.svg", -- optional, feel free to change
        "location_picker": "photo", -- optional, background layer to pinpoint the hotel
      }
    }
}

Applying tags to already existing features

For this, the tag_apply-button can be used.

The following example uses the calculated tags _has_closeby_feature and _closest_osm_hotel. These were added by a small extra script using calculatedTagss.


 {
    "id": "tag-apply-button",
    "condition": "_has_closeby_feature=yes", -- don't show if no feature to add to
    "render": {
      "special": {
        "type": "tag_apply",
        "tags_to_apply": "$tags", -- note the '$', property containing the tags
        "id_of_object_to_apply_this_one": "_closest_osm_hotel" -- id of the feature to add those tags to
        "message": {
          "en": "Add all the suggested tags"
        },
        "image": "./assets/svg/addSmall.svg",
      }
    }
  }

Creating a maproulette challenge

A challenge can be created on https://maproulette.org/admin/projects

This can be done with a geojson-file (or by other means).

To create an import dataset, make a geojson file where every feature has a tags-field with ';'-seperated tags to add. Furthermore, setting the property blurb can be useful.

(The following example is not tested and might be wrong.)

{
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "geometry": {"type": "Point", "coordinates": [1.234, 5.678]},
            "properties": {
                "tags": "foo=bar;name=xyz",
                "blurb": "Please review this item and add it..."
            }
        
        }
    
    ] 
}