{"id":20213455,"url":"https://github.com/maproulette/mr-cli","last_synced_at":"2025-04-10T13:51:32.045Z","repository":{"id":40718795,"uuid":"261547217","full_name":"maproulette/mr-cli","owner":"maproulette","description":"CLI utility to generate MapRoulette cooperative challenges, add task attachments, etc.","archived":false,"fork":false,"pushed_at":"2023-12-29T17:16:46.000Z","size":205,"stargazers_count":4,"open_issues_count":5,"forks_count":3,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-03-26T21:45:20.366Z","etag":null,"topics":["maproulette","openstreetmap"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/maproulette.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-05T18:04:55.000Z","updated_at":"2022-11-29T11:58:38.000Z","dependencies_parsed_at":"2024-11-14T06:06:50.085Z","dependency_job_id":"31a48fa0-38be-4e6a-b200-201ffed7e10b","html_url":"https://github.com/maproulette/mr-cli","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maproulette%2Fmr-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maproulette%2Fmr-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maproulette%2Fmr-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maproulette%2Fmr-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maproulette","download_url":"https://codeload.github.com/maproulette/mr-cli/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248228495,"owners_count":21068699,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["maproulette","openstreetmap"],"created_at":"2024-11-14T06:06:46.136Z","updated_at":"2025-04-10T13:51:32.009Z","avatar_url":"https://github.com/maproulette.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mr-cli MapRoulette Command Line Interface Utility\n\nThe mr-cli package provides a `mr` command-line utility intended to offer\nvarious tools for working with [MapRoulette](https://maproulette.org).\n\nUse `mr --help` for a list of top-level commands, and `mr \u003ccommand\u003e --help` for\nusage and options available for a specific command.\n\n\n## Prerequisites\n- [Node.js](https://nodejs.org) (v12.15 LTS or higher)\n- [npm](http://npm.js)\n\n\n## Installation\nInstalling globally allows you to run the `mr` command from anywhere.\n\n```\nnpm install -g @maproulette/mr-cli\n```\n\n## Upgrading\nRepeating the installation command will upgrade a global copy to the latest\nversion.\n\n```\nnpm install -g @maproulette/mr-cli\n```\n\n\n## Creating Cooperative Challenges\nCooperative challenges associate existing, uncomitted, in-progress work with\neach task. That work is then presented to MapRoulette mappers for final\ncompletion or verification.\n\nThe `mr cooperative` command can be used to generate GeoJSON with cooperative tasks\nsuitable for upload to MapRoulette during creation of a new challenge. It\nrequires the desired type of cooperative tasks to be specified: `change` for\nstandard cooperative tasks with attached change files, which allows for inclusion\nof unrestricted edits; or `tag` for special tag-only fixes that can be\ncompleted and committed to OpenStreetMap fully within MapRoulette without need\nfor an external editor.\n\nOne or more change files -- either saved\n[JOSM (.osm)](https://wiki.openstreetmap.org/wiki/JOSM_file_format) files or\n[OSMChange (.osc)](https://wiki.openstreetmap.org/wiki/OsmChange) files --\nmust be given as the final parameter to the `mr cooperative` command. The\nfiles will be processed and \"line-by-line GeoJSON\" suitable for uploading to\nMapRoulette during challenge creation will be output.\n\nBy default, the GeoJSON is written to the standard output. You can easily\nspecify the name of an output file instead with the `--out` parameter.\n\n\u003e :warning: the `mr cooperative` command is **EXPERIMENTAL**. Please carefully\n\u003e and diligently inspect the generated tasks as this tool almost certainly\n\u003e contains bugs\n\n\n### JOSM Workflow\n1. Make edits in JOSM\n2. Save file -- **don't** upload to OSM. If you want full control over which\n   edits go into each task, save the work for each task into its own file\n3. Use `mr cooperative` with your saved JOSM file(s) to generate a MapRoulette\n   challenge file\n4. Create a new MapRoulette challenge and choose to upload a local file,\n   providing the challenge file\n\n\n### Generating Cooperative Tasks with Attached Change Files\nBasic Syntax:\n\n```\nmr cooperative change [--out \u003cchallenge-file\u003e] [--bijective] [--dev] \u003cinput-files..\u003e\n```\n\nTo generate a standard cooperative challenge with tasks containing unrestricted\nchanges represented by one or more change files (either JOSM .osm or OSMChange\n.osc), use the `mr cooperative change` command. The work-in-progress changes\nwill be served to the mapper in their editor during task completion so that\nthey can finish or verify the work. Final work is then saved to OSM by the\nmapper through their editor just as they would for their own edits in a normal\ntask.\n\nJOSM files do not organize individual edits into groups, so, by default, each\n*top-level modification* found in the JOSM file(s) (that is, modifications not\nreferenced by other modifications in the same file) will be represented as a\nsingle task in the challenge file. For example, if the file contained new\nbuildings where each building had new nodes and a new way that referenced those\nnodes as members, then tasks would only be created for the new ways (and not\nthe new nodes since they are referenced by the ways).\n\nIf you need more control over which modifications are grouped into which task,\nthen save each group of related modifications into its own file and use the\n`--bijective` option to create one task per file.\n\nOSMChange (.osc) files do allow for some basic grouping of individual\nmodifications, and so all edits in each \"action\" group will be represented as a\nsingle task. For more control, separate the related modifications into their\nown files and use the `--bijective` option, just as with JOSM files.\n\nSometimes elements in a change file reference other elements for which the data\nisn't included in the file. `mr` often needs the data in order to generate\ncorrect GeoJSON geometry for the task, and so in that case it will contact OSM\nand fetch the referenced element data when needed.\n\n\u003e If your change file is based on data from the OSM dev servers, then you also\n\u003e need to add the `--dev` flag so that the OSM dev servers are contacted\n\u003e instead of the production servers\n\n#### Example 1: Adding new, unrelated OSM nodes\nAssume some new benches (nodes) are to be added. As each edit (node addition)\nstands on its own, we can save all of these together in a single JOSM file if\ndesired, and will have every edit turned into a separate MapRoulette task.\n\nWe will read input data from a `new_benches.osm` JOSM file we saved and have\nthe outputted challenge GeoJSON saved to a file called\n`new_bench_challenge.json`.\n\n```\nmr cooperative change --out new_bench_challenge.json new_benches.osm\n```\n\n#### Example 2: Adding related, heirarchical modifications\nNow we wish to add some buildings, which will include new nodes and a way for\neach building. Even though each building contains multiple new OSM elements --\nnodes and a way -- these additions are heirarchical, with the nodes playing a\nsupporting role for the way. `mr` will generate new tasks only for the top-level\nchanges (the ways in this case), and will simply bundle in the supporting changes\n(the nodes) rather than creating separate tasks for them.\n\n```\nmr cooperative change --out new_buildings_challenge.json new_buildings.osm\n```\n\n#### Example 3: Manually grouping related modifications together\nSometimes the default behavior doesn't group modifications into tasks quite the\nway you'd like, and so full control over which modifications end up together in\neach task is needed. This can be done by saving each group of related\nmodifications together into its own file and then feeding all the files in with\nthe `--bijective` option to create a one-to-one mapping from files to tasks in\nthe outputted GeoJSON. This gives you complete control over what ends up in\neach task.\n\nOne real-world example at the time of writing would be adjusting building\noutlines by repositioning their nodes. Since the building's way is not itself\npart of the changes -- only the nodes -- each modified node will be top-level\nand, therefore, would by default become a separate task. The `mr` tool isn't\nsmart enough (yet!) to realize that multiple modified nodes are part of the\nsame (unmodified) way and should perhaps be grouped together. We obviously\ndon't want a separate task for each node in this case, so the solution is to\nsave each modified building into its own file and use the `--bijective` option.\n\nWe'll assume we saved our files as `building_1.osm`, `building_2.osm`,\netc. The naming doesn't matter as long as you can easily reference all the\nfiles -- we'll do so here using wildcards. We'll save the challenge GeoJSON to\na file called `outlines_challenge.json`.\n\n```\nmr cooperative change --out outlines_challenge.json --bijective building*.osm\n```\n\n\n### Generating Cooperative Tasks with Tag-Only Fixes\nBasic Syntax:\n\n```\nmr cooperative tag [--out \u003cchallenge-file\u003e] [--dev] \u003cinput-files..\u003e\n```\n\nIf your changes consist purely of tag fixes, an alternative \"tag fix\" (formerly\nquick fix) style cooperative challenge can be generated instead with the `mr\ncooperative tag` command. MapRoulette will present the proposed tag changes to\nmappers during task completion and allow them to approve or reject the changes\nwithin MapRoulette, as well as modify the tags if needed. Approved changes are\nsubmitted directly to OSM by MapRoulette itself, removing the need for external\neditors.\n\nOne or more change files must be provided. Note that only one edit can be\nrepresented by each tag fix cooperative task, so each modification found in the\nchange file(s) will be represented as a single task in the challenge file.\nThere is no ability to manually group edits for tag fix tasks, and any grouping\nin an OSMChange file will be ignored.\n\nTag-fixes for each task are computed by comparing the proposed state in the\nchange file with the versions of OpenStreetMap data *referenced in the file*\n(which may not necessarily be the very latest version at the time `mr` is run)\nand then analyzing the differences.\n\n\u003e If your change file is based on data from the OSM dev servers, then you also\n\u003e need to add the `--dev` flag so that the OSM dev servers are contacted\n\u003e instead of the production servers\n\nWhen the tag fix is presented to a mapper in MapRoulette, the latest OSM data\nwill first be fetched so that only pertinent tag changes are shown to the\nmapper.\n\n\n## Attaching Data To Tasks\n\nMapRoulette v3.6.5 and above support data attachments to tasks. Please see the\n[MapRoulette\ndocs](https://learn.maproulette.org/documentation/task-attachments/)\nfor details on what kinds of attachments are supported.\n\nThe mr-cli utility can be used to add attachments to tasks in an existing\nline-by-line GeoJSON file, producing a new GeoJSON file with the attachments\nincluded.\n\nAttachment files are matched to tasks based on specified feature properties,\nattachment filenames, and optional match patterns.\n\nBasic Syntax:\n\n```\nmr attach task [--in \u003cchallenge-file\u003e] [--out \u003cchallenge-file\u003e] \u003ckind|as-is\u003e \u003cauto-detect|type\u003e \u003cfile-pattern\u003e [property-pattern] [property] [format] [encode]\n```\n\n#### Example 1: Attach GPX reference layers based on OSM id\nAssume that we have a `my_challenge.geojson` file and that each task has an\n`osmid` feature property formatted like `n1234`, `n5678`, etc., and that\nour respective attachment files are named `attachment_n1234.gpx`,\n`attachment_n5678.gpx`, and so on.\n\nIn order for mr-cli to know how to match up which file with which task, it's\nnecessary to provide a *file pattern* that shows mr-cli how to build the filename\nfor each task based on the value of a feature property. In this case, we need to\ntell mr-cli to use the value of the `osmid` property in the filename, which we\ncan do by surrounding it with curly braces as so: `attachment_{osmid}.gpx`\n\n\u003e Note: only one property may be referenced in a filename pattern\n\nSo here is our full command. We'll output the updated challenge to an\n`updated_challenge.geojson` and we'll also use the `--auto-detect` option to\nautomatically detect that we're working with GPX files.\n\n```\nmr attach task --in my_challenge.geojson --out updated_challenge.geojson --kind referenceLayer --auto-detect --file-pattern 'attachment_{osmid}.gpx'\n```\n\n#### Example 2: Attaching multiple reference layers to tasks\nBuilding on Example 1 above, the file pattern can include wildcard characters\nthat can be used to match multiple files. All matching files will be included\nas attachments. Perhaps we have both a GPX layer and an OSM layer for each task.\n\n\u003e :warning: to match different types of files you **must** use the `--auto-detect`\n\u003e option. If an explicit type is specified instead, all matching files will be\n\u003e treated as that type\n\nOur command is the same as in example 1, but includes a `*` for the file\nextension to potentially match multiple files per osmid:\n\n\u003e Patterns should be surrounded by single quotes when used on the command line\n\u003e to avoid potential conflicts with special shell characters\n\n```\nmr attach task --in my_challenge.geojson --out updated_challenge.geojson --kind referenceLayer --auto-detect --file-pattern 'attachment_{osmid}.*'\n```\n\n#### Example 3: Extracting only relevant parts of property value\nBuilding on Example 1, what if our `osmid` property was instead formatted\nas `node/1234`, `node/4567` while our files were still named `attachment_n1234.gpx`,\n`attachment_n5678.gpx`, and so on? We'll need to extract the first letter of the\ntype as well as the numeric id. mr-cli makes that possible through *property\npatterns*.\n\nProperty patterns are standard [regular\nexpressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Cheatsheet),\nand you can use capture groups (parentheses) to extract just parts of the\nproperty value. Only the captured parts will be substituted into the filename\npattern (in the order in which they are captured).\n\nHere is a regular expression that will capture the first letter (\"word\" character),\nignore everything that follows that isn't a digit, and then capture all the remaining\ndigits: `(\\w)[^\\d]+(\\d+)`\n\n\u003e Note: when a property pattern is used, only tasks with a matching value will\n\u003e be considered. That means property patterns can also be used to limit\n\u003e attachments to matching tasks even if you don't need to use capture groups\n\nWe'll use this in our command. This is the same command as in Example 1 except now\nwe specify a `--property-pattern` option with our regular expression\n\n\u003e Note: backslashes need to be escaped when used on the command line and\n\u003e therefore appear as `\\\\` when regular expressions are shown in example mr-cli\n\u003e commands\n\n```\nmr attach task --in my_challenge.geojson --out updated_challenge.geojson --kind referenceLayer --auto-detect --property-pattern '(\\\\w)[^\\\\d]+(\\\\d+)' --file-pattern 'attachment_{osmid}.gpx'\n```\n\n#### Example 4: More control over the filename pattern\nIn Example 3, we were able to continue referencing `{osmid}` in our filename\npattern because we were lucky to want exactly the captured data in exactly the\norder it appeared in the property value. That may not always be the case, and\nit can be useful to have more control over where each captured portion of the\nproperty value appears in your filename.\n\nBuilding on Example 3, let's assume our filenames are instead named\n`attachment_node_1234.gpx`, `attachment_node_4567.gpx`, etc. We now need to\ncapture the full OSM type and the numeric id, but separate them with an\nunderscore in the filename pattern.\n\nOur updated property pattern: `(\\w+)[^\\d]+(\\d+)`\nOur updated filename pattern: `attachment_\\1_\\2.gpx`\n\nSince our filename pattern no longer refers to `osmid` explicitly, we also need\nto provide a `--property` option that tells mr-cli to look at the `osmid`\nproperty.\n\n```\nmr attach task --in my_challenge.geojson --out updated_challenge.geojson --kind referenceLayer --auto-detect --property osmid --property-pattern '(\\\\w+)[^\\\\d]+(\\\\d+)' --file-pattern 'attachment_\\\\1_\\\\2.gpx'\n```\n\n#### Example 5: Specifying an explicit file type\nSo far we've always used the `--auto-detect` option, which inspects the actual\nattachment data (not the filename) to try to determine what type of file it\nrepresents. You can also explicitly specify the type if you want. Note, however,\nthat only one type can be specified.\n\nHere is the command from Example 1 with the gpx type explicitly specified:\n\n```\nmr attach task --in my_challenge.geojson --out updated_challenge.geojson --kind referenceLayer --type gpx --file-pattern 'attachment_{osmid}.xml'\n```\n\n#### Example 6: Attaching blobs\nMapRoulette supports attachments of arbitrary data as blobs. These are intended\nfor attachments that are to be consumed by external processes, and are ignored\nby MapRoulette.\n\nWhen attaching blobs, use of `--format` is recommended, and if the data isn't\nJSON-compatible (i.e. XML or binary data), then `--encode` must be specified or\nyou'll end up with malformed GeoJSON.\n\nHere is an example command that attaches arbitrary XML data as a blob. Note\nthat `--format xml` has been specified and `--encode` has also been provided.\n\n```\nmr attach task --in my_challenge.geojson --out updated_challenge.geojson --kind blob --format xml --encode --file-pattern 'attachment_{osmid}.xml'\n```\n\n#### Using your own generated attachments as-is\nNormally the mr-cli tool takes your raw attachment files and builds all of the\nproper task attachment JSON required by MapRoulette, as\n[documented](https://learn.maproulette.org/documentation/task-attachments/).\nBut if you've generated your own complete attachment JSON files conforming to\nthe documentation, you can ask mr-cli to simply use your files as-is by using\nthe `--as-is` option. The only augmentation mr-cli may perform is to generate\n`id` fields for your attachments if missing.\n\n```\nmr attach task --in my_challenge.geojson --out updated_challenge.geojson --as-is --file-pattern 'attachment_{osmid}.json'\n```\n\n#### Mixing multiple kinds of attachments\nmr-cli only allows one kind of attachment (such as blobs or reference layers)\nin a single run, but you can add additional kinds of attachments with\nadditional runs on the output. The additional matching attachments will be\nadded to tasks as needed, leaving earlier attachments intact.\n\nIt's even possible to pipe multiple mr-cli runs together using the standard\ninput and standard output. For example, the following attaches blobs followed\nby reference layers. Note that the first command does not include an `--out`,\nthereby sending its results to the standard output, and the second command\nomits the `--in` so that it reads from the standard input:\n\n```\nmr attach task --in my_challenge.geojson --kind blob --format xml --encode --file-pattern 'blobs_{osmid}.xml' | mr attach task --out updated_challenge.geojson --kind referenceLayer --auto-detect --file-pattern 'layers_{osmid}.gpx'\n```\n\n\n### Additional Notes\n- Generated challenge files use a\n[line-by-line](https://learn.maproulette.org/documentation/line-by-line-geojson/)\nformat that is well suited to streaming, whereby each line in the file contains a\ncomplete GeoJSON object representing a single task in the challenge. It may not be\npossible to open or manipulate this file using traditional GeoJSON tools\n\n- As of v0.1.2, [RFC 7464](https://tools.ietf.org/html/rfc7464) compliant\nline-by-line GeoJSON is generated by default. If you must upload your challenge\nto a MapRoulette instance earlier than v3.6.5, you can specify `--no-rfc7464`\nto generate the old format.\n\n- This utility has not been tested on Windows\n\n\n## Development\n1. Clone the repo\n2. `npm install` to install NPM packages\n\nRun with `npm run mr -- \u003ccommand\u003e`. If you're writing to the standard output,\nuse `npm --silent run mr` so that the generated GeoJSON isn't polluted with\nstatus messages from NPM.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaproulette%2Fmr-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaproulette%2Fmr-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaproulette%2Fmr-cli/lists"}