Modify

Opened 6 months ago

Closed 5 months ago

Last modified 4 months ago

#15606 closed enhancement (fixed)

[patch] export relation to GPX file or convert to a new GPX layer (e.g. for further editing such as simplify way)

Reported by: cmuelle8 Owned by: team
Priority: normal Milestone: 17.12
Component: Core Version: latest
Keywords: export gpx relation route superroute Cc:

Description (last modified by cmuelle8)

I've tackled on the lack of an export feature for route relations,
and this is what I've come up with..

..in the hope it will be useful to someone.

The algorithm runs recursively on the found relation members,
but ignores incomplete relations (i.e. downloading of incomplete
relations is not done automatically currently, but could be added).

  • sort order of the relations is untouched and roles forward/backward are recognized
  • single-membered roundabouts are silently skipped (i.e. no new trkSeg is started)
  • loops (forward/backward) should be handled correctly (i.e. one direction is ignored, depending on the menu entry chosen)

The aim is primarily to reply a single segmented track from A to B, but if the sort
order of the relation does not provide this, multiple track segments for the generated
GPX are created. We could run the relationSorter and try to fix a broken order before
GPX export, but this discourages users to actually fix broken route relations, so the
algorithm _intentionally_ takes the sort order of the relation as they are.


Feel free to test or modify,
Greetings

Attachments (2)

josm-export-route-relations-to-GPX-file_or_convert-to-GPX-layer.png (56.8 KB) - added by cmuelle8 6 months ago.
josm-export-route-relations-to-GPX-file_or_convert-to-GPX-layer.patch (36.7 KB) - added by cmuelle8 6 months ago.
rework layer and segment naming, generate uniq names, generate single-segmented tracks by default (multiple tracks should generally only occur, if the relations are broken, unsorted or have wrong/incomplete forward/backward roles)

Download all attachments as: .zip

Change History (26)

comment:1 Changed 6 months ago by cmuelle8

Description: modified (diff)

added image to description

comment:2 Changed 6 months ago by cmuelle8

Description: modified (diff)

comment:3 Changed 6 months ago by cmuelle8

Last patch revision adds

  • prettified GPX Info dialog (cell padding)
  • GPX Info show segments per track and total segments for the gpx layer
  • added option to split a GPX layer with multiple tracks to multiple layers with one track each

All added options to the context menu of GPX layer are shown in expert mode (see settings) only,
and only if they apply to the current data the gpx layer holds.

The added options are:

  • combine multiple tracks into one track within the same gpx layer
  • split track segments of a single track to multiple tracks with one segment each (within the same gpx layer)
  • split multiple tracks of current gpx layer to multiple gpx layers with one track (the current gpx layer is not modified)

Each has their own action class (inner classes of GpxLayer.java).

comment:4 Changed 6 months ago by Don-vip

This seems strange in GpxData:

        attrs.put("name", attrs.get("name").toString().replaceFirst(" #\\d+$", ""));

        attrs.put("name", MessageFormat.format("{0}{1}", name, (count > 1) ? " #"+count : ""));

comment:5 Changed 6 months ago by Don-vip

This won't be translated correctly:

        String segs = "";
        if (data.getTrackSegsCount() > data.getTrackCount()) {
            segs = " (" + data.getTrackSegsCount() + " segment" + (data.getTrackSegsCount() > 1 ? "s)" : ")");
        }
        info.append(trn("{0} track{1}, ", "{0} tracks{1}, ", data.getTracks().size(), data.getTracks().size(), segs, segs))

comment:6 Changed 6 months ago by Don-vip

GpxDataTest needs to be updated too (compilation error).

comment:7 Changed 6 months ago by Don-vip

Milestone: 17.12

Otherwise it seems really good :) I only reviewed the code and did not test the function yet.

comment:8 in reply to:  4 Changed 6 months ago by cmuelle8

Replying to Don-vip:

This seems strange in GpxData:

        attrs.put("name", attrs.get("name").toString().replaceFirst(" #\\d+$", ""));

        attrs.put("name", MessageFormat.format("{0}{1}", name, (count > 1) ? " #"+count : ""));
  • 2nd line produces unique names in the event that more than one tracks (with exactly one segment each) result from traveling the route relation (i.e. if it is broken or unsorted) OR from splitting an existing gpx track with multiple segments into tracks (.. with one segment each)
  • 1st line ensures that the name suffix does not grow when split / combine actions are called repeatedly, e.g. to avoid Interesting Route #2 #2 #2 after three iterations, this line is probably only important when (count>0) is used instead (or when the track has been saved, first segment removed and reimported, so that a #2 suffixed segment is at the start of the track list).

If you have a better idea how to solve this, comment.

I'll rework the translation bit..

comment:9 Changed 6 months ago by Don-vip

The first line currently does nothing, as the value is overridden by the second statement. You probably wanted to write attrs.get("name") instead of name?

comment:10 Changed 6 months ago by cmuelle8

@Don-vip: yep, you're right

  • first line got refactored to the wrong method, should be part of the combining method only
  • thanks for pinpointing me the second time

Here comes the updated patch that also fixes the unit test and the translation issue..

Changed 6 months ago by cmuelle8

rework layer and segment naming, generate uniq names, generate single-segmented tracks by default (multiple tracks should generally only occur, if the relations are broken, unsorted or have wrong/incomplete forward/backward roles)

comment:11 Changed 5 months ago by Don-vip

Resolution: fixed
Status: newclosed

In 13210/josm:

fix #15606 - export relation to GPX file or convert to a new GPX layer (patch by cmuelle8, modified)

comment:12 Changed 5 months ago by Don-vip

Thanks a lot! I have only modified minor code style issues. You can check them with ant clean compile pmd checkstyle.

comment:13 Changed 5 months ago by Don-vip

In 13211/josm:

see #15606 - update unit test

comment:14 Changed 5 months ago by holgermappt

The messages need some improvements to make them translatable into other languages. Especially the "first"/"last" messages are not translatable at the moment. E.g. this in ExportRelationToGpxAction.java:

    public ExportRelationToGpxAction(EnumSet<Mode> mode) {
        super(tr("{0} starting from {1} member",
                 mode.contains(TO_FILE) ? tr("Export GPX file") : tr("Convert to GPX layer"),
                 mode.contains(FROM_FIRST_MEMBER) ? tr("first") : tr("last")),

Please do not assume that the order of words and inflection of first/last is the same in all languages in the world. To make it translatable we need complete sentences, not a word puzzle. So that needs to be 4 sentences.

Please make this two strings, one starting with "first" and one starting with "last":

              tr("Flatten this relation to a single gpx track "+
                 "recursively, starting with the {0} member(s), "+
                 "successively continuing to the {1}.",
                 mode.contains(FROM_FIRST_MEMBER) ? tr("first") : tr("last"),
                 mode.contains(FROM_FIRST_MEMBER) ? tr("last") : tr("first")),

If it can be "member" and "members" in English then that need to be 2 trn().

comment:15 in reply to:  14 Changed 5 months ago by Don-vip

Replying to holgermappt:

The messages need some improvements to make them translatable into other languages. Especially the "first"/"last" messages are not translatable at the moment.

You're right.

If it can be "member" and "members" in English then that need to be 2 trn().

This would be difficult as we don't know the relation when creating the action.

comment:16 Changed 5 months ago by Don-vip

In 13216/josm:

see #15606 - i18n fix

comment:17 Changed 5 months ago by cmuelle8

thanks, will try to keep this in mind for future activities..

comment:18 Changed 5 months ago by Klumbumbus

The mouseover hint says e.g. "...starting with the first member(s)...". How can the first member be plural?

comment:19 in reply to:  18 ; Changed 5 months ago by cmuelle8

Replying to Klumbumbus:

The mouseover hint says e.g. "...starting with the first member(s)...". How can the first member be plural?

There may either be a first member or some first members, which is why the s is put within parentheses.

Compare

  • the first natural number
  • 1, 2, 3 are among the first natural numbers
  • the first couple/triple/(..) in a row

"First" is an attribute to qualify a position in an ordered set, but it does not constrain the object qualified to be singular. Do you have a reference that stands in contradiction?

Even in places where the "first" commonly is a singularity, say a race, there is the rare case of a shared first place, i.e. two or more first places, if the contestants where measured to have done equally well with respect to the game rules.

That being said, it's probably pedantic to account for this here, so I do not oppose using the singular form instead, if you consider this bug.

Last edited 5 months ago by cmuelle8 (previous) (diff)

comment:20 Changed 5 months ago by Klumbumbus

Yes I understand the "grammar background". However in this context I think plural makes no sense. I can't imagine a case where there are several equal first members in a route relation.

I think for the user it is easier to understand without the plural s, so he doesn't need to think about it when it is plural, like me :)

comment:21 in reply to:  19 ; Changed 5 months ago by holgermappt

Replying to cmuelle8:

There may either be a first member or some first members, which is why the s is put within parentheses.

@cmuelle8: Out of curiosity: Do you have an example of a relation with multiple first or last members? I looked at the definition of a relation (e.g. https://wiki.openstreetmap.org/wiki/OSM_XML), and I think there is always exactly one first and one last element (or no first/last if it is an empty relation). I can select multiple relations and call your function, but I assume then you process the relations one-by-one, so it will be still one first/last member. Or do you think of the case where the first/last element is another relation with multiple members?

The "member(s)" looks fishy, as if you forgot to use the singular/plural version of tr(), see the last sentence in comment:14.

comment:22 in reply to:  21 Changed 5 months ago by cmuelle8

Replying to holgermappt:

The "member(s)" looks fishy, as if you forgot to use the singular/plural version of tr(), see the last sentence in comment:14.

This whole discussion is taking the route of making an elephant of a mouse. If the majority of coders here does not like it, then change it, I'm in no way personally assaulted by such a change.

Keep in mind that it's problematic to mix a technical specification with user directed, natural language messages.

  • Technically there may be exactly one first member, if the spec formalizes on this.
  • The "grammar background" in natural language allows imprecision that is resolved by context (and in part, the expertise of the reader).

The user messages IMHO are not constraint to match technical formalizations. I agree that it's nice if they incidentally do. In fact the grammar background is rather intriguing, there may be:

  • exactly a first member
  • multiple first members with identical qualities (like in the race example above, with a shared first position).
  • multiple first members that are subordinate wrt each other (like 1, 2, 3 are among the first members of (the first) 100 natural numbers).

In the last case, if the temporal view as a unit of these first members is "unwrapped", we could recursively make out first members until exactly a first member is found.


Regarding osm relation data, we may encounter all three cases within the realm of route relations, you may stumble upon:

  • exactly the first member
  • multiple first members with identical qualities, e.g. the route is shaped like an 8 ("eight") and the middle segment
    • must be driven twice in the same direction to complete the whole course
    • is listed (in a duplicate fashion) as first an second member (1st and 2nd member are the first members)
  • multiple first members that are subordinate, e.g. the route has 420 way members, in order, then
    • natural language defines the first members vaguely or fuzzily
    • the term does not define cardinality of the set of first members, it may refer to
      • the first two, three or ten members ..
      • the first ten percent of all members, etc.

To close this post: Yes, sorry, I have probably contributed to making an elephant of this.

Last edited 4 months ago by cmuelle8 (previous) (diff)

comment:23 Changed 5 months ago by Klumbumbus

Yes, further discussion is a waste of time. I'll change it next week after end of stabilization phase.

comment:24 Changed 4 months ago by Klumbumbus

In 13292/josm:

see #15606 - adjust mouse over hint text

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain team.
as The resolution will be set.
The resolution will be deleted.

Add Comment


E-mail address and name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.