JOSM Search and Replace?

I wish to edit the name key of a group of nodes to fix typos and normalize data. For instance, I want to change the first character of names places starting with "El " to "el ".

Currently I have a good filter rule in JOSM, so I can edit each node by hand easilly. But I would be easier selecting all desired nodes and replacing "El " to "el " with a single click. There are many typos in many nodes.

Is it possible to do what I’m seeking?

Thanks for your help!

Joan Montané

What you want to do is possible after you install the scripting plugin. Let me know if you want an example in Python.

Jo

Thanks for quick reply,

yes, please provide me a sample basic script. Days ago I installed script plugin, but I’m unable to achieve nothing usefull.

Something like:

Iterate in each node/way/relation in user’s current selection
If name match a regex ("El "), replace name with regex (s/^El /el /).

Regards,
Joan Montané

First of all, you have to install Jython and tell the scripting plugin where to find its executable.

This is probably more than you bargained for:

http://josm.openstreetmap.de/wiki/Help/Plugin/Scripting/Python/RCN_Route_Validator

You’ll have to remove a lot for your purpose, but it’s all there; iterating over objects in the selection, regular expressions. I hope it can inspire you.

Jo

Thanks! I’ve created a simple proof-of-concept script, :slight_smile: Now I’m dealing with undo-feature.

Regards,
Joan Montané

I used in the past scripting and a javascript or jython script to do that.
Unfortunately I can’t install scripting since at least one year (JOSM under macOS).

Is there a plan to add this basic functionality natively in JOSM ?

If not, is it possible to use MapCSS to do this ?
i.e. by creating a specific validation rule ?

My use case is to replace the wrong separator in start_date
start_date=2025/02/11 > start_date=2025-02-11

Try asking for help at GitHub - Gubaer/josm-scripting-plugin: Task automation in the OpenStreetMap editor JOSM.

In my opinion there are several reason why this feature is an addon. Why do you need it in core?

Sure MapCSS can do this with a simple regex and an auto-fix to replace your separator is possible
Untested:

*[start_date][start_date =~ /^\d{4}(\/\d\d){2}$/] {
  throwWarning: tr("{0} with backslash as separator", "{0.key}");
  fixAdd: concat("{0.key}", "=", replace(tag("{0.key}"), "/", "-"));
  set start_date_syntax
}
*[start_date][start_date !~ /^\d{4}(-\d\d){2}$/]!.start_date_syntax {
throwWarning: tr("{0} with incomplete or wrong value", "{0.key}");
}

If the values of start_date are an bigger issue a ticket to get it into core might be useful but if above is working and useful, I can add it as external rule.

Like a “basic” text editor for.coders, simply search en replace several patterns.
Currently we must save JOSM data in .osm, search and replace with the text editor, reload the file in JOSM.
The problem is that is an object is modified, we must add action='modify', so this isn’t easy and error prone.

Yes I read the doc in the meantime.
I will test your code, thank you :grinning:

I will check with taginfo if there is a lot of similar issue with start_date, end_date, check_date, abandoned:date, survey:date…

We could expand CheckDate to check other *date tags and fix them if necessary.

Yes, but as it would be used only by a small group of users, it’s a reason to keep it out of core. By the way, do you know the Comfort0 plugin?

  1. Create a new data layer and switch back to your data
  2. Select the objects in question using JOSM search (maybe with MapCSS syntax and regex
  3. Merge selected objects to previously created new layer
  4. Switch to new layer and add FIXME=search_and_replace to all objects (to get the modified state)
  5. Save layer to file
  6. Search & replace in text editor
  7. Load file
  8. Remove FIXME=search_and_replace if not already done in text editor
  9. Upload or merge layer to original data layer

With comfort0 this list shortens dramatically and it is basically only the JOSM search or filters to get the correct objects selected and exported to your text editor.

:+1:

Nice find. The regex looks better than my simple approach.

No, so nice. Thank you

I remember now, I did that :sweat_smile:

:+1:

I wrote and test this:

meta {
    title: "Check Dates";
    version: "0.1";
    author: "Pyrog";
    link: "";
    baselanguage: "en";
}

*[start_date][start_date       !~/^\d{4}(-[01]\d(-\d\d([T ]\d\d:\d\d:\d\dZ?)?)?)?$/ ],
*[end_date][end_date           !~/^\d{4}(-[01]\d(-\d\d([T ]\d\d:\d\d:\d\dZ?)?)?)?$/ ],
*[check_date][check_date       !~/^\d{4}(-[01]\d(-\d\d([T ]\d\d:\d\d:\d\dZ?)?)?)?$/ ],
*["survey:date"]["survey:date" !~/^\d{4}(-[01]\d(-\d\d([T ]\d\d:\d\d:\d\dZ?)?)?)?$/ ]
{
  throwWarning: "{0.key} should be a valid ISO 8601 date (YYYY-MM-DD)";
  set invalid_ISO_8601_date
}

*[start_date    =~ /\//],
*[end_date      =~ /\//],
*[check_date    =~ /\//],
*["survey:date" =~ /\//]
{
  throwWarning: tr("{0} with backslash as separator", "{0.key}");
  fixAdd: concat("{0.key}", "=", replace(tag("{0.key}"), "/", "-"));
  set start_date_syntax
}

Some common errors in date are i.e. France 31/12/2025 :arrow_right: 2025-12-31
… but I didn’t provide a fix.
Must be used carefully with i.e. 01-02-2025. Is it first february or january, 2nd ? :laughing:

Source, survey, check start and end dates in this order with the following separators .-/\
Overpass query return around 100 000 objects !