[PATCH] apply_local action (variable substitution in relation members)

On the Finnish forum, the senior mapper alv pointed out that the left:*, right:* names for boundary=administrative ways are being made obsolete by boundary relations. I agree with him that boundary relations are the better option, especially with regards to localization. mkgmap can replace name with some other tag, such as name:sv for Swedish, but it would be difficult to have it replace a family of left:*, right:* tags with left:*:sv, right:*:sv. So, I tried to define a relations rule that would generate a space-separated list of names for a boundary line. For example, the boundary=administrative line http://www.openstreetmap.org/browse/way/38589207 that belongs to the relations of the city borders Vantaa and Helsinki and to the Helsinki suburban borders Tapulikaupunki and Suutarila should get all these names, "Vantaa/Helsinki/Tapulikaupunki/Suutarila", in some order. What happens is that it will get just one of the names, "Suutarila" in my test run: In the relations file, I had this, trying to append each relation name to the mkgmap:boundary_name attribute of each relation member: (type=boundary | type=multipolygon) & boundary=administrative & name=* { echo '${name}'; apply { set mkgmap:boundary_name='${mkgmap:boundary_name}/${name}' | '${name}'; echo '${mkgmap:boundary_name}' } } The problem is that within apply{}, the variable substitutions on the right-hand-side of the "set" and "add" action always refer to the tags of the relation, not to the relation member. Thus, mkgmap:boundary_name will always be empty, and only one relation name will be copied to it. One possible solution is to have a special form of apply{} where SubAction.performOnSubElements(Relation rel) does not invoke addTagAction.setValueTags(rel). A patch that introduces the action apply_local{} is attached. An alternative solution would be to have a special form of variable substitution that refers to the tags of the element itself. One simple way of implementing that could be to introduce the keywords set_local and add_local and add another boolean parameter to AddTagAction that would imply valueTags == null. Yet another solution would be to have a special syntax of variable substitution that would bypass the valueTags, say, $(var) instead of ${var}: (type=boundary | type=multipolygon) & boundary=administrative & name=* { apply { set mkgmap:boundary_name='$(mkgmap:boundary_name)/${name}' | '${name}'; } } Best regards, Marko

Hi, Maybe I am being impatient, but I would have expected some feedback to this patch. As far as I understand, it is not currently possible to catenate attributes from multiple relations to a map element. Is really nobody trying to achieve that? For example, bus routes overlap on main streets. How would you replace the street name (on a bus route map layer) with a list of bus route names or refs that use the street? Best regards, Marko

On 16.12.2009 09:03, Marko Mäkelä wrote:
Hi,
Maybe I am being impatient, but I would have expected some feedback to this patch. As far as I understand, it is not currently possible to catenate attributes from multiple relations to a map element. Is really nobody trying to achieve that? For example, bus routes overlap on main streets. How would you replace the street name (on a bus route map layer) with a list of bus route names or refs that use the street?
Best regards,
Well I'm using add relation:name {name} .... scheme and rules to catch it back in the lines file., same for ref. I can't really understand what your patch would make better.
Marko _______________________________________________ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Hi Felix, On Wed, Dec 16, 2009 at 09:07:23AM +0100, Felix Hartmann wrote:
On 16.12.2009 09:03, Marko Mäkelä wrote:
Hi,
Maybe I am being impatient, but I would have expected some feedback to this patch. As far as I understand, it is not currently possible to catenate attributes from multiple relations to a map element. Is really nobody trying to achieve that? For example, bus routes overlap on main streets. How would you replace the street name (on a bus route map layer) with a list of bus route names or refs that use the street?
Best regards,
Well I'm using add relation:name {name} .... scheme and rules to catch it back in the lines file., same for ref.
I can't really understand what your patch would make better.
How do you combine the names from several name or ref? Let's assume that you are making a bus route map, and there are two bus route relations, ref=1 and ref=2, and a section of Main Street belongs to both. How would you write the rules so that the street would be named "Main Street (1,2)"? Alternatively, how would you copy the names of all boundary=administrative relations to the lines that belong to the boundary relation? There usually are at least two boundary relations per boundary line, sometimes several (at different administrative levels). Marko

Hi all, Steve Ratcliffe confirmed the existence of this problem to me in a private message. In the next few days, I plan to implement special syntax for variable substitution, because it will allow shorter style rules to be written. See an example of the syntax at the bottom of my original message below. Best regards and sorry for top-posting, Marko On Mon, Dec 14, 2009 at 11:41:05PM +0200, Marko Mäkelä wrote:
The problem is that within apply{}, the variable substitutions on the right-hand-side of the "set" and "add" action always refer to the tags of the relation, not to the relation member. Thus, mkgmap:boundary_name will always be empty, and only one relation name will be copied to it.
One possible solution is to have a special form of apply{} where SubAction.performOnSubElements(Relation rel) does not invoke addTagAction.setValueTags(rel). A patch that introduces the action apply_local{} is attached.
An alternative solution would be to have a special form of variable substitution that refers to the tags of the element itself. One simple way of implementing that could be to introduce the keywords set_local and add_local and add another boolean parameter to AddTagAction that would imply valueTags == null.
Yet another solution would be to have a special syntax of variable substitution that would bypass the valueTags, say, $(var) instead of ${var}:
(type=boundary | type=multipolygon) & boundary=administrative & name=* { apply { set mkgmap:boundary_name='$(mkgmap:boundary_name)/${name}' | '${name}'; } }

On Dec 21, 2009, at 9:52, Marko Mäkelä wrote:
In the next few days, I plan to implement special syntax for variable substitution, because it will allow shorter style rules to be written. See an example of the syntax at the bottom of my original message below.
Thanks. I have not had time to look into this, but I also noticed that a lot of boundaries within Germany cannot get appropriate descriptions due to this problem. Will logical comparisons also work with the variable substitution? That is, something like the following: name != $(name:en) { ... } This would make it easier to avoid redundant information in names. (Such as, in the example above, adding the English name only if it is not equal to the name.) Earlier, i submitted a patch which introduced a not-equal filter which did this for me, but the patch was never committed: it would be great if there was a standard solution for this. Cheers.

On Mon, Dec 21, 2009 at 12:08:26PM +0100, Clinton Gladstone wrote:
Will logical comparisons also work with the variable substitution? That is, something like the following:
name != $(name:en) { ... }
This would make it easier to avoid redundant information in names. (Such as, in the example above, adding the English name only if it is not equal to the name.)
I understood the source code so that variable substitution would only work in the right-hand-side of 'add', 'name', and 'set' rules. I believe that the special name:* handling would be best implemented in a special mkgmap option. I would try to avoid writing language suffixes in style files. Styles can be globally useful, and the selection of preferred language(s) is merely a parameter that should be passed to mkgmap on the command line. Perhaps something like this: mkgmap --define name:LANG=name:en
Earlier, i submitted a patch which introduced a not-equal filter which did this for me, but the patch was never committed: it would be great if there was a standard solution for this.
Would the not-equal filter be used something like this: name '${name} (${name:LANG|ne:${name}}) | ${name}' The ne: would be a not-equal filter, meaning that '${name} (${name:LANG})' will be used when ${name} is not equal to ${name:LANG}. I see value in this; having a secondary language in parentheses could be useful in multilingual areas or for foreign tourists. Best regards, Marko

On Dec 21, 2009, at 20:20, Marko Mäkelä wrote:
I believe that the special name:* handling would be best implemented in a special mkgmap option. I would try to avoid writing language suffixes in style files.
The question of the logical comparisons is to avoid redundancies, some of which may not be related to the language. An example would be if the name and the ref of a road are identical: if so, only one, not both, should be set for the name.
Earlier, i submitted a patch which introduced a not-equal filter which did this for me, but the patch was never committed: it would be great if there was a standard solution for this.
Would the not-equal filter be used something like this:
name '${name} (${name:LANG|ne:${name}}) | ${name}'
Here is an example from my style file: place=* {name '${name} (${name:en|not-equal:name})' | '${name} (${int_name|not-equal:name})' | '${name} (${name:zh_py|not-equal:name})' | '${name}' } This will place one of the following values in parenthesis after the name, as long as the value is not identical to the name: - The English name - The international name - The Pinyin romanization of the name (useful for place names in China) As you can see, the intent is to add multilingual values to the map. As in the case of the international name, the name chosen is not necessarily specific to a certain language. So what do you think of this? ;-) Cheers.

Clinton, On Tue, Dec 22, 2009 at 01:23:48AM +0100, Clinton Gladstone wrote:
Here is an example from my style file:
place=* {name '${name} (${name:en|not-equal:name})' | '${name} (${int_name|not-equal:name})' | '${name} (${name:zh_py|not-equal:name})' | '${name}' }
This will place one of the following values in parenthesis after the name, as long as the value is not identical to the name:
- The English name - The international name - The Pinyin romanization of the name (useful for place names in China)
OK, this is very useful. I would propose two things: 1. commit the not-equal filter to mkgmap 2. implement include files, possibly also a mkgmap --include option so that you could include the "Chinese sub-style" from the command line when needed, for any style whose definitions do not conflict with those in the sub-style.
As you can see, the intent is to add multilingual values to the map. As in the case of the international name, the name chosen is not necessarily specific to a certain language.
So what do you think of this? ;-)
Your example shows that the name rules could be best defined in a style file. Can you submit a patch for implementing include files in the style parser? And can you please resubmit the not-equal filter? Marko

On Dec 22, 2009, at 10:29, Marko Mäkelä wrote:
OK, this is very useful. I would propose two things:
1. commit the not-equal filter to mkgmap 2. implement include files, possibly also a mkgmap --include option so that you could include the "Chinese sub-style" from the command line when needed, for any style whose definitions do not conflict with those in the sub-style.
I'll be quite happy to resubmit the patch. I would like to hear the opinion of others before it is committed though: I'm not sure if this is a good approach to the problem. The include option is something else: as I am neither familiar with the code in question nor am I an experienced Java programmer, this might take somewhat longer. ;-) Cheers.

1. commit the not-equal filter to mkgmap ... I'll be quite happy to resubmit the patch. I would like to hear the opinion of others before it is committed though: I'm not sure if this is a good approach to the problem.
I have this set up ready to commit, if no one has any comments.
The include option is something else: as I am neither familiar with the code in question nor am I an experienced Java programmer, this might take somewhat longer. ;-)
It is possible to base styles on other existing styles. This is like taking a style and then adding to it overriding anything that conflicts. See the noname style to see how this is done - you add a 'base-style' option to the info file in the style. This might be not quite what is needed but it worth knowing about. ..Steve

On Tue, Dec 22, 2009 at 02:01:54PM +0000, Steve Ratcliffe wrote:
It is possible to base styles on other existing styles. This is like taking a style and then adding to it overriding anything that conflicts. See the noname style to see how this is done - you add a 'base-style' option to the info file in the style. This might be not quite what is needed but it worth knowing about.
Thank you Steve, I was not aware of that. I will have a look at that and see if I can create a simple family of styles that is based on the default style. I might even start using the noname style myself and add stuff to it, for highlighting incompletely mapped items, such as * highway=crossing without crossing=* * highway=bus_stop without shelter=yes/no * highway=bus_stop,shelter=yes without lit=yes/no Best regards, Marko

On Dec 22, 2009, at 15:01, Steve Ratcliffe wrote:
1. commit the not-equal filter to mkgmap ... I'll be quite happy to resubmit the patch. I would like to hear the opinion of others before it is committed though: I'm not sure if this is a good approach to the problem.
I have this set up ready to commit, if no one has any comments.
You may notice that I have added a new protected attribute to class ValueFilter called 'element'. The current element is assigned to this attribute, which makes it possible to extract tags, etc., in the filter method. This could potentially be useful for other filters, but I was unsure if this was an appropriate change. At least with my casual observations, I have not noted any significant increase in memory or CPU use. However, if no one else has any concerns, it would be nice to have this committed. It opens some other interesting possibilities for filters. Cheers.

On 12/22/2009 03:03 PM, Clinton Gladstone wrote:
You may notice that I have added a new protected attribute to class ValueFilter called 'element'. The current element is assigned to this attribute, which makes it possible to extract tags, etc., in the filter method. This could potentially be useful for other filters, but I was unsure if this was an appropriate change. At least with my casual observations, I have not noted any significant increase in memory or CPU use.
I don't think it would cause any problems with memory or cpu, but if an extra argument is added to filter() then I would add the same one to doFilter() since they are the really the same routine just split so that the common code can be in the base class. Of course that means that almost all the implementations will not use one of the args. ..Steve

On Dec 23, 2009, at 0:55, Steve Ratcliffe wrote:
I don't think it would cause any problems with memory or cpu, but if an extra argument is added to filter() then I would add the same one to doFilter() since they are the really the same routine just split so that the common code can be in the base class.
I updated the patch as you suggested and have attached it. I'd appreciate it if you could consider committing the patch. Cheers.

Clinton Gladstone wrote:
On Dec 21, 2009, at 20:20, Marko Mäkelä wrote:
I believe that the special name:* handling would be best implemented in a special mkgmap option. I would try to avoid writing language suffixes in style files.
The question of the logical comparisons is to avoid redundancies, some of which may not be related to the language. An example would be if the name and the ref of a road are identical: if so, only one, not both, should be set for the name.
Earlier, i submitted a patch which introduced a not-equal filter which did this for me, but the patch was never committed: it would be great if there was a standard solution for this. Would the not-equal filter be used something like this:
name '${name} (${name:LANG|ne:${name}}) | ${name}'
Here is an example from my style file:
place=* {name '${name} (${name:en|not-equal:name})' | '${name} (${int_name|not-equal:name})' | '${name} (${name:zh_py|not-equal:name})' | '${name}' }
This will place one of the following values in parenthesis after the name, as long as the value is not identical to the name:
- The English name - The international name - The Pinyin romanization of the name (useful for place names in China)
As you can see, the intent is to add multilingual values to the map. As in the case of the international name, the name chosen is not necessarily specific to a certain language.
Just to point out that someone else has been working on a front-end transliterator for OSM data to be processed in mkgmap: http://forum.openstreetmap.org/viewtopic.php?id=5554 -- Charlie

On Mon, Dec 14, 2009 at 11:41:05PM +0200, Marko Mäkelä wrote:
Yet another solution would be to have a special syntax of variable substitution that would bypass the valueTags, say, $(var) instead of ${var}:
(type=boundary | type=multipolygon) & boundary=administrative & name=* { apply { set mkgmap:boundary_name='$(mkgmap:boundary_name)/${name}' | '${name}'; } }
I implemented this (see the attached patch). It was easier than I thought, and the runtime penalty should be low. Unless someone complains, I will commit this patch tomorrow. Marko

On Dec 21, 2009, at 21:54, Marko Mäkelä wrote:
On Mon, Dec 14, 2009 at 11:41:05PM +0200, Marko Mäkelä wrote:
Yet another solution would be to have a special syntax of variable substitution that would bypass the valueTags, say, $(var) instead of ${var}:
(type=boundary | type=multipolygon) & boundary=administrative & name=* { apply { set mkgmap:boundary_name='$(mkgmap:boundary_name)/${name}' | '${name}'; } }
I implemented this (see the attached patch). It was easier than I thought, and the runtime penalty should be low.
Hm... I tried this out, however I couldn't get a name for the following boundary which runs down the middle of the Rhine: http://www.openstreetmap.org/?lat=49.23141&lon=8.38788&zoom=16&layers=B000FT... This I suppose is a rather complicated example, as the line in question is an administrative boundary without a name, but it has five relations defining various boundaries. Am I doing something wrong, or does the way this item was tagged prevent the name from being displayed? Cheers.

Hi Clinton, On Tue, Dec 22, 2009 at 04:45:20PM +0100, Clinton Gladstone wrote:
Hm... I tried this out, however I couldn't get a name for the following boundary which runs down the middle of the Rhine:
http://www.openstreetmap.org/?lat=49.23141&lon=8.38788&zoom=16&layers=B000FT...
This I suppose is a rather complicated example, as the line in question is an administrative boundary without a name, but it has five relations defining various boundaries. Am I doing something wrong, or does the way this item was tagged prevent the name from being displayed?
I do not see anything obviously wrong in the data. According to the wiki, Germany uses type=multipolygon relations instead of type=boundary, but the styles/default/lines should accept both. The boundary lines around here are similar (relations with multiple admin levels) and work just fine: http://www.openstreetmap.org/?lat=60.359479&lon=25.155142&zoom=18&layers=B00... I added the left:city, right:city on the boundary lines before I learned that the names naturally belong to relations, not to the boundary lines. The left:*, right:* rules will not kick in in the default style. Also the suburban borders in Helsinki obtain correct names from the relations, as you can see in my Finnish map at http://www.polkupyoraily.net/osm/. In Hämeenlinna, boundaries are named both by left:suburban, right:suburban and by relations. The relations must have been added there some time this year. I hope that this helps you further. By the way, this forum discussion about misnamed boundaries in mkgmap-generated German maps could be related: http://forum.openstreetmap.org/viewtopic.php?id=5707 Best regards, Marko
participants (5)
-
Charlie Ferrero
-
Clinton Gladstone
-
Felix Hartmann
-
Marko Mäkelä
-
Steve Ratcliffe