Skip to content

Possibility to add JOSM XML attributes to individual objects #278

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
gabortim opened this issue Jan 28, 2025 · 14 comments
Closed

Possibility to add JOSM XML attributes to individual objects #278

gabortim opened this issue Jan 28, 2025 · 14 comments

Comments

@gabortim
Copy link

My typical workflow is as follows:

  1. Retrieve some OSM data
  2. Make the necessary changes using console scripts (e.g. osmium)
  3. Review the edits in JOSM
  4. Upload the changes via JOSM

To make the history viewer work in step 3 and display the upload button in step 4, the modified objects from step 2 need to include the action=modify attribute, as described in the JOSM file format documentation.

Is this functionality currently supported in the latest release? If not, could you please consider adding it?

Additionally, I am unsure if this works with formats other than XML. However, since XML is human-readable, I believe it would suffice for most use cases.

JOSM r19293
osmium 4.0.2 (Python 3.12.8)

@joto
Copy link
Member

joto commented Jan 29, 2025

This is unlikely to get supported because the XML is written by the libosmium library which doesn't support the special JOSM additions to the file format. To support this we'd need to somehow store those extra "action" bits somewhere and make them accessible in the interface.

But I believe JOSM can read .osc files which can be generated with (Py)Osmium, so it should be possible to generate these instead.

@gabortim
Copy link
Author

But I believe JOSM can read .osc files which can be generated with (Py)Osmium, so it should be possible to generate these instead.

Ah, you're right! Thanks for the suggestion.

However, I'm encountering an issue with .osc generation in PyOsmium. If a modified object is original (its version number is 1), it gets a <create> tag instead of <modify> in the osc file. Is it intended?

@joto
Copy link
Member

joto commented Jan 29, 2025

That's how the .osc file works. By definition an object with version 1 is always "created", an object with version >1 is always "modified".

@gabortim
Copy link
Author

That’s strange. According to the documentation:

The upload API call supports placeholders - in fact, all id attributes in create elements are treated as placeholders whether negative or not.

So if I modify an existing (version 1) object and it gets a <create> tag, the upload API will treat its ID as a placeholder and still upload it, effectively creating a duplicate. Is that correct?

I also checked OSMand, and it uses <modify> in these cases, which seems to align better with the expected behavior.

@joto
Copy link
Member

joto commented Jan 29, 2025

All of this stuff is really not that well documented and the behaviour may well be different in different applications. My understanding is that if you change an object you must give it a new version number. I can not see any difference between modify and create, under the hood in OSM the only thing that ever happens is that a new version of some object is added, a create or modify or delete is always just a new version of an object. But this is probably not the right place to discuss this, because it is not related to PyOsmium, but something that has to do with the API and JOSM behaviour.

@lonvia
Copy link
Member

lonvia commented Jan 31, 2025

@joto is correct, pyosmium leaves writing files completely to libosmium. So the feature request needs to go there first. Although it sounds like diff files is the better way to go for you.

Closing here as "currently not possible".

@lonvia lonvia closed this as not planned Won't fix, can't repro, duplicate, stale Jan 31, 2025
@gabortim
Copy link
Author

Thanks for the input! The diff would be perfect, but since it adds a tag to existing objects, I can't use it. 😕
I could work around it, of course, but the whole point of using an external library is to avoid that.

@lonvia
Copy link
Member

lonvia commented Jan 31, 2025

You can (and in fact, should) simply increase the version before writing your modified data into the diff file. pyosmium doesn't do that automatically for you but you can do it manually.

@gabortim
Copy link
Author

gabortim commented Feb 6, 2025

Could you please tell me which part should I look at? The only thing I found is a read-only version number upon processing.

@lonvia
Copy link
Member

lonvia commented Feb 6, 2025

You can change the version like any other attribute when writing out data using the replace function, see Writing data in the user manual.

Here is a simple script that increases the version of all objects and writes them out again:

import osmium

with osmium.SimpleWriter('out.osc') as  writer:
    for o in osmium.FileProcessor('in.opl'):
        writer.add(o.replace(version=o.version + 1))

An in.opl file with a single node:

n1 v1 x45.0 y13.0

Results in the expected modify output:

<?xml version='1.0' encoding='UTF-8'?>
<osmChange version="0.6" generator="libosmium/2.19.0">
  <modify>
    <node id="1" version="2" lat="13" lon="45"/>
  </modify>
</osmChange>

@gabortim
Copy link
Author

gabortim commented Feb 23, 2025

Thanks for the suggestion, but I use BackReferenceWriter and the version bumping doesn't seem to work with that writer class. It just ignores the whatever I write there.

Input (in.opl):

n1 v1 x45.0 y13.0

Osmium script:

import osmium

with osmium.BackReferenceWriter("out.osc", ref_src="in.opl", overwrite=True, remove_tags=False) as writer:
    for o in osmium.FileProcessor("in.opl") \
            .with_areas() \
            .with_filter(osmium.filter.GeoInterfaceFilter()) \
            .with_filter(osmium.filter.EntityFilter(osmium.osm.NODE | osmium.osm.WAY | osmium.osm.RELATION)):
        o.replace(version=o.version + 1)
        writer.add(o)

Output (out.osc):

<?xml version='1.0' encoding='UTF-8'?>
<osmChange version="0.6" generator="libosmium/2.20.0">
  <create>
    <node id="1" version="1" lat="13" lon="45"/>
  </create>
</osmChange>

@gabortim
Copy link
Author

I've edited my previous comment to add an example. I'm curious if this is something that can be solved out of the box.

@lonvia
Copy link
Member

lonvia commented Feb 23, 2025

The replace function returns a copy of the object. You have to write out the copy. Change your code as follows:

...
        new_object = o.replace(version=o.version + 1)
        writer.add(new_object)
...

and it should work with the backreference writer as well.

@gabortim
Copy link
Author

*facepalm* Thanks! Case closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants