
Hi, I have tweaked my maps recently and tripped on some problems. Nothing serious, but a bit troublesome. First I noticed, that tweak for better looking roundabouts not always works. In default style there is something like that: junction=roundabout & (highway=tertiary | highway=tertiary_link) [0x0c road_class=1 road_speed=1 resolution 24 continue] junction=roundabout & (highway=tertiary | highway=tertiary_link) [0x10804 resolution 21] I have noticed, that sometimes I get roundabout partially covered by line 0x10804. Maybe mkgmap is splitting roundabout and a part of it is written into img after line 0x10804? Sorry, I have reworked my style and can't provide an example now. Then I got problems with --make-opposite-cycleways. Looks like this option is not executed at finalize step, but the created line gets full processing in style. If there exist somewhere a roundabout with opposite cycle line, then default style will create double lines 0x10804. Safe version of style would be: mkgmap:synthesised!=yes & junction=roundabout & (highway=tertiary | highway=tertiary_link) [0x10804 resolution 21] Then I have found that following doesn't work: if (mkgmap:synthesised!=yes) then junction=roundabout & (highway=tertiary | highway=tertiary_link) [0x10804 resolution 21] end Result: Mkgmap version 4902 Time started: Sun May 29 21:47:50 CEST 2022 SEVERE (global): Error in style: Error: (lines:15): Invalid rule, expression cannot be indexed: $mkgmap:synthesised!=yes SEVERE (global): Could not open style But this one works: if (mkgmap:synthesised=yes) then else junction=roundabout & (highway=tertiary | highway=tertiary_link) [0x10804 resolution 21] end I understand, that there is some kind of optimization for keywords, but why one type of condition works while others don't? Mkgmap accepts "keyword=false" but not "keyword=!true" nor "!(keyword=true)". If this is unavoidable, then would be nice to get a warning in manual. Finally I made an error in style and crashed mkgmap. I wrote something like this: if (mkgmap:style-option:test=true) then () echo {"test"} end and got following: Mkgmap version 4902 Time started: Sun May 29 21:06:03 CEST 2022 SEVERE (global): Unexpected error java.lang.NullPointerException: Cannot invoke "uk.me.parabola.mkgmap.osmstyle.eval.Op.isType(uk.me.parabola.mkgmap.osmstyle.eval.NodeType)" because the return value of "uk.me.parabola.mkgmap.osmstyle.eval.Op.getFirst()" is null at uk.me.parabola.mkgmap.osmstyle.ExpressionArranger.selectivity(ExpressionArranger.java:381) at uk.me.parabola.mkgmap.osmstyle.ExpressionArranger.arrangeAndChain(ExpressionArranger.java:348) at uk.me.parabola.mkgmap.osmstyle.ExpressionArranger.arrangeTop(ExpressionArranger.java:95) at uk.me.parabola.mkgmap.osmstyle.ExpressionArranger.arrange(ExpressionArranger.java:74) at uk.me.parabola.mkgmap.osmstyle.RuleFileReader.loadFile(RuleFileReader.java:132) at uk.me.parabola.mkgmap.osmstyle.RuleFileReader.load(RuleFileReader.java:102) at uk.me.parabola.mkgmap.osmstyle.StyleImpl.readRules(StyleImpl.java:303) at uk.me.parabola.mkgmap.osmstyle.StyleImpl.<init>(StyleImpl.java:158) at uk.me.parabola.mkgmap.osmstyle.StyleImpl.readStyle(StyleImpl.java:546) at uk.me.parabola.mkgmap.reader.osm.OsmMapDataSource.createConverter(OsmMapDataSource.java:324) at uk.me.parabola.mkgmap.reader.osm.OsmMapDataSource.setupHandler(OsmMapDataSource.java:206) at uk.me.parabola.mkgmap.reader.osm.OsmMapDataSource.parse(OsmMapDataSource.java:166) at uk.me.parabola.mkgmap.reader.osm.OsmMapDataSource.load(OsmMapDataSource.java:142) at uk.me.parabola.mkgmap.main.MapMaker.loadFromFile(MapMaker.java:165) at uk.me.parabola.mkgmap.main.MapMaker.makeMap(MapMaker.java:58) at uk.me.parabola.mkgmap.main.Main.lambda$processFilename$1(Main.java:291) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) at java.base/java.lang.Thread.run(Thread.java:833) SEVERE (global): Exiting due to unexpected error Number of ExitExceptions: 1 -- Best regards, Andrzej

Hi, Am 29.05.22 um 22:10 schrieb Andrzej Popowski:
First I noticed, that tweak for better looking roundabouts not always works. In default style there is something like that:
junction=roundabout & (highway=tertiary | highway=tertiary_link) [0x0c road_class=1 road_speed=1 resolution 24 continue] junction=roundabout & (highway=tertiary | highway=tertiary_link) [0x10804 resolution 21]
I have noticed, that sometimes I get roundabout partially covered by line 0x10804. Maybe mkgmap is splitting roundabout and a part of it is written into img after line 0x10804? Sorry, I have reworked my style and can't provide an example now.
this is how I create roundabouts with an invisible routing 0x0c and a visible 0x11e0X on top: junction=roundabout & highway=trunk [0x11e04 level 5 continue] junction=roundabout & highway=trunk [0x0c road_class=1 road_speed=2 level 6] junction=roundabout & highway=primary [0x11e04 level 5 continue] junction=roundabout & highway=primary [0x0c road_class=1 road_speed=2 level 5] junction=roundabout & highway=secondary [0x11e05 level 4 continue] junction=roundabout & highway=secondary [0x0c road_class=1 road_speed=2 level 4] junction=roundabout & highway=tertiary [0x11e06 level 3 continue] junction=roundabout & highway=tertiary [0x0c road_class=1 road_speed=2 level 3] junction=roundabout & highway=unclassified [0x11e07 level 3 continue] junction=roundabout & highway=unclassified [0x0c road_class=1 road_speed=2 level 3] junction=roundabout [0x11e07 level 3 continue] junction=roundabout [0x0c road_class=1 road_speed=2 level 2] Has always worked for me. Have you tried to swap your two config lines?

Hi Ralf, I had similar style: overlay line first, roundabout next. I can't repeat the problem, maybe it was my fault. Now I'm using transparent graphics for 0x0c, so it looks correct regardless of order. -- Best regards, Andrzej

Hi Andrzej, a) the option --make-opposite-cycleways is implemented like this; 1) before(!) style processing mkgmap looks at the OSM way and detects a possible need for a cycleway. If so, it creates a copy of the OSM way with tags for bicylce access only and mkgmap:synthesised=yes 2) still before style processing it sets bicycle=no for the original OSM way 3) it passes the original way through the style processing 4) it passes the copy through the style processing b) Your rule if (mkgmap:synthesised!=yes) then junction=roundabout & (highway=tertiary | highway=tertiary_link) [0x10804 resolution 21] end The manual has this note: "There used to be some restrictions on the kind of expression you could use. Now the only restriction is you must have at least one test that depends on a tag existing. So you cannot match on everything, regardless of tags, or test for an object that does not have a tag." Your rule could indeed be changed to junction=roundabout & (highway=tertiary | highway=tertiary_link) & mkgmap:synthesised!=yes [0x10804 resolution 21] so I wonder why mkgmap complains. Seems it checks only the "if" part. That would also explain the crash with the invalid statement. Gerd ________________________________________ Von: mkgmap-dev <mkgmap-dev-bounces@lists.mkgmap.org.uk> im Auftrag von Andrzej Popowski <popej@poczta.onet.pl> Gesendet: Sonntag, 29. Mai 2022 22:10 An: mkgmap-dev@lists.mkgmap.org.uk Betreff: [mkgmap-dev] Some observations Hi, I have tweaked my maps recently and tripped on some problems. Nothing serious, but a bit troublesome. First I noticed, that tweak for better looking roundabouts not always works. In default style there is something like that: junction=roundabout & (highway=tertiary | highway=tertiary_link) [0x0c road_class=1 road_speed=1 resolution 24 continue] junction=roundabout & (highway=tertiary | highway=tertiary_link) [0x10804 resolution 21] I have noticed, that sometimes I get roundabout partially covered by line 0x10804. Maybe mkgmap is splitting roundabout and a part of it is written into img after line 0x10804? Sorry, I have reworked my style and can't provide an example now. Then I got problems with --make-opposite-cycleways. Looks like this option is not executed at finalize step, but the created line gets full processing in style. If there exist somewhere a roundabout with opposite cycle line, then default style will create double lines 0x10804. Safe version of style would be: mkgmap:synthesised!=yes & junction=roundabout & (highway=tertiary | highway=tertiary_link) [0x10804 resolution 21] Then I have found that following doesn't work: if (mkgmap:synthesised!=yes) then junction=roundabout & (highway=tertiary | highway=tertiary_link) [0x10804 resolution 21] end Result: Mkgmap version 4902 Time started: Sun May 29 21:47:50 CEST 2022 SEVERE (global): Error in style: Error: (lines:15): Invalid rule, expression cannot be indexed: $mkgmap:synthesised!=yes SEVERE (global): Could not open style But this one works: if (mkgmap:synthesised=yes) then else junction=roundabout & (highway=tertiary | highway=tertiary_link) [0x10804 resolution 21] end I understand, that there is some kind of optimization for keywords, but why one type of condition works while others don't? Mkgmap accepts "keyword=false" but not "keyword=!true" nor "!(keyword=true)". If this is unavoidable, then would be nice to get a warning in manual. Finally I made an error in style and crashed mkgmap. I wrote something like this: if (mkgmap:style-option:test=true) then () echo {"test"} end and got following: Mkgmap version 4902 Time started: Sun May 29 21:06:03 CEST 2022 SEVERE (global): Unexpected error java.lang.NullPointerException: Cannot invoke "uk.me.parabola.mkgmap.osmstyle.eval.Op.isType(uk.me.parabola.mkgmap.osmstyle.eval.NodeType)" because the return value of "uk.me.parabola.mkgmap.osmstyle.eval.Op.getFirst()" is null at uk.me.parabola.mkgmap.osmstyle.ExpressionArranger.selectivity(ExpressionArranger.java:381) at uk.me.parabola.mkgmap.osmstyle.ExpressionArranger.arrangeAndChain(ExpressionArranger.java:348) at uk.me.parabola.mkgmap.osmstyle.ExpressionArranger.arrangeTop(ExpressionArranger.java:95) at uk.me.parabola.mkgmap.osmstyle.ExpressionArranger.arrange(ExpressionArranger.java:74) at uk.me.parabola.mkgmap.osmstyle.RuleFileReader.loadFile(RuleFileReader.java:132) at uk.me.parabola.mkgmap.osmstyle.RuleFileReader.load(RuleFileReader.java:102) at uk.me.parabola.mkgmap.osmstyle.StyleImpl.readRules(StyleImpl.java:303) at uk.me.parabola.mkgmap.osmstyle.StyleImpl.<init>(StyleImpl.java:158) at uk.me.parabola.mkgmap.osmstyle.StyleImpl.readStyle(StyleImpl.java:546) at uk.me.parabola.mkgmap.reader.osm.OsmMapDataSource.createConverter(OsmMapDataSource.java:324) at uk.me.parabola.mkgmap.reader.osm.OsmMapDataSource.setupHandler(OsmMapDataSource.java:206) at uk.me.parabola.mkgmap.reader.osm.OsmMapDataSource.parse(OsmMapDataSource.java:166) at uk.me.parabola.mkgmap.reader.osm.OsmMapDataSource.load(OsmMapDataSource.java:142) at uk.me.parabola.mkgmap.main.MapMaker.loadFromFile(MapMaker.java:165) at uk.me.parabola.mkgmap.main.MapMaker.makeMap(MapMaker.java:58) at uk.me.parabola.mkgmap.main.Main.lambda$processFilename$1(Main.java:291) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) at java.base/java.lang.Thread.run(Thread.java:833) SEVERE (global): Exiting due to unexpected error Number of ExitExceptions: 1 -- Best regards, Andrzej _______________________________________________ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk https://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Hi Gerd, thanks for explanations.
the option --make-opposite-cycleways is implemented like this
Somehow I imagined, that opposite cycleway is magically added at a final step, when the main road is already prepared by style. Your way is more flexible, but needs more diligence in style. Actually I had to make a lot corrections in my style, when I realized how it works. It would be good to add your explanation to options.txt.
The manual has this note:
"There used to be some restrictions on the kind of expression you could use. Now the only restriction is you must have at least one test that depends on a tag existing. So you cannot match on everything, regardless of tags, or test for an object that does not have a tag." Sorry, I missed it. It is at the section, "Combining tag tests", while I was interested in a single test. I read the section "Allowed operations" and found no difference between using tag=value and tag!=value. This make me wonder, why "mkgmap:option:test=true" works but "mkgmap:option:test!=true" doesn't. To be true, I'm not understanding this explanation. What does it mean "tag existing"? Does tag "highway" exist but "mkgmap:synthesised" doesn't?
I wonder why mkgmap complains. Seems it checks only the "if" part.
I guess it is about "if then", most problems appear when I try to use this statement. Another question: is the condition of "if then" statement checked once or for each line included in the conditional block? I wonder whether "if then" could optimize processing of style. -- Best regards, Andrzej

Hi Andrzej, to be honest, I don't understand enough of the rule parsing to improve the syntax. I don't even know for sure why mkgmap:option:test!=true { add foo=bar} is not supported. Might be coding complexity, might be run time performance. On the other hand you already found the work around to use if (mkgmap:option:test=true) then else { add foo=bar} end I don't think that if-then can improve performance. The rules are not compiled in a way that would allow to skip something. On the other hand a lot of caching happens so that in rules like junction=roundabout & (highway=trunk | highway=trunk_link) [0x0c road_class=4 road_speed=2 resolution 24 continue] junction=roundabout & (highway=trunk | highway=trunk_link) [0x10801 resolution 18] the common expression is stored only once and the result of the first evaluation is simply reused in the 2nd rule. With the next rule junction=roundabout & (highway=primary | highway=primary_link) & mkgmap:fast_road=yes [0x0c road_class=4 road_speed=2 resolution 24 continue] the expression junction=roundabout is again reused and only the other expressions are computed. Only problem: When an action changes any tag of the object all cached results are cleared. Gerd ________________________________________ Von: mkgmap-dev <mkgmap-dev-bounces@lists.mkgmap.org.uk> im Auftrag von Andrzej Popowski <popej@poczta.onet.pl> Gesendet: Montag, 30. Mai 2022 13:51 An: mkgmap-dev@lists.mkgmap.org.uk Betreff: Re: [mkgmap-dev] Some observations Hi Gerd, thanks for explanations.
the option --make-opposite-cycleways is implemented like this
Somehow I imagined, that opposite cycleway is magically added at a final step, when the main road is already prepared by style. Your way is more flexible, but needs more diligence in style. Actually I had to make a lot corrections in my style, when I realized how it works. It would be good to add your explanation to options.txt.
The manual has this note:
"There used to be some restrictions on the kind of expression you could use. Now the only restriction is you must have at least one test that depends on a tag existing. So you cannot match on everything, regardless of tags, or test for an object that does not have a tag." Sorry, I missed it. It is at the section, "Combining tag tests", while I was interested in a single test. I read the section "Allowed operations" and found no difference between using tag=value and tag!=value. This make me wonder, why "mkgmap:option:test=true" works but "mkgmap:option:test!=true" doesn't. To be true, I'm not understanding this explanation. What does it mean "tag existing"? Does tag "highway" exist but "mkgmap:synthesised" doesn't?
I wonder why mkgmap complains. Seems it checks only the "if" part.
I guess it is about "if then", most problems appear when I try to use this statement. Another question: is the condition of "if then" statement checked once or for each line included in the conditional block? I wonder whether "if then" could optimize processing of style. -- Best regards, Andrzej _______________________________________________ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk https://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Hi Gerd,
On the other hand you already found the work around
Kind of blind search for solution. I have implemented some kind of processing in style, where I need temporary variables. Now I have a long sequence, where i only use operator "=" for variables, since "!=" doesn't work :)
I don't think that if-then can improve performance.
Ok, thanks for insight on working of mkgmap. I think mkgmap is really fast, but I'm always tempted to make some improvements. -- Best regards, Andrzej

Hi Firstly: I don't get a crash from: if (mkgmap:style-option:test=true) then () echo {"test"} end with or without --style-option=test. Also, don't you mean "... mkgmap:option:test ..." Next: The "test" part of a rule must contain at least 1 "positive" limiting clause, as per the style-manual paragraph already mentioned. The best limiting clause is used first when determining if an object meets the condition. Secondly: My understanding is that if/then/else requires the same positive limiting in the "if" condition and then just incorporates the "if" condition into all of the "then" conditions and !(ifcond) into all of the "else" conditions, so that: if (ifCond) then (thenCond1) {thenAct1} (thenCond2) {thenAct2} else (elseCond) {elseAct} end is, apart from the extra constraint on "ifCond" mentioned above, just the same as if you had written: (ifCond) & (thenCond1) {thenAct1} (ifCond) & (thenCond2) {thenAct2} !(ifCond) & (elseCond1) {elseAct1} The full "else" test also require positive limiting and this can only come from the "elseCond". Attempting: if (someTag=*) then else () {actionIfNotSet} end won't fool the rule processor and you'll get the "Invalid rule, unable to index" error. Finally: If you really want some action based on missing tags, then you can use the --style-option=x to set a tag on all elements and then use this along with the required negative test eg: if (mkgmap:option:x=true & mkgmap:synthesized!=yes) then (junction=roundabout ...) {...} (...) {...} end but this will probably be less efficient than writing: mkgmap:synthesized!=yes & junction=roundabout & ... {...} mkgmap:synthesized!=yes & ... {...} because, when written with "if", every object matches the first processed clause, but when written without, the first thing evaluated is junction=roundabout Ticker

Hi Ticker!
I don't get a crash
Maybe there are other factors? I'm using AMD Ryzen, Windows 10, OpejJDK 18.0.1 (just have updated, 17.02 worked the same). I can create a set which cause crash, if you are interested. Right, it should be mkgmap:option:test, but I get a crash in both cases.
The "test" part of a rule must contain at least 1 "positive" limiting clause, as per the style-manual paragraph already mentioned.
So "tag existing" or "positive" means, that "test" have to include at least one check/condition equivalent to "tag=value" (including "tag=*")? If I only use single check, then I have to use "tag=value" and nothing else. It is OK, only not the common situation in programming.
The full "else" test also require positive limiting and this can only come from the "elseCond". Attempting:
if (someTag=*) then else () {actionIfNotSet} end
won't fool the rule processor and you'll get the "Invalid rule, unable to index" error.
It doesn't work, but this works: if (mkgmap:option:test=true) then else highway=* {...} end while these don't work (but should?): if (mkgmap:option:test!=true) then highway=* {...} end if (!(mkgmap:option:test=true)) then highway=* {...} end -- Best regards, Andrzej

Hi Andrez On Tue, 2022-05-31 at 00:23 +0200, Andrzej Popowski wrote:
Hi Ticker!
> I don't get a crash
Maybe there are other factors? I'm using AMD Ryzen, Windows 10, OpejJDK 18.0.1 (just have updated, 17.02 worked the same). I can create a set which cause crash, if you are interested. Right, it should be mkgmap:option:test, but I get a crash in both cases.
I just noticed that, rather than: if (mkgmap:style-option:test=true) then () {echo "test"} end , you had: if (mkgmap:style-option:test=true) then () echo {"test"} end which does crash the expression handler. I doubt if this is worth investigating / fixing.
> The "test" part of a rule must contain at least 1 "positive" limiting > clause, as per the style-manual paragraph already mentioned.
So "tag existing" or "positive" means, that "test" have to include at least one check/condition equivalent to "tag=value" (including "tag=*")?
Yes, and < <= >= = ~ are also acceptable, but functions, eg area_size(), is_complete() etc are not.
If I only use single check, then I have to use "tag=value" and nothing else. It is OK, only not the common situation in programming.
Not sure what you mean.
> The full "else" test also require positive limiting and this can only > come from the "elseCond". Attempting: > > if (someTag=*) then > else > () {actionIfNotSet} > end > > won't fool the rule processor and you'll get the "Invalid rule, unable > to index" error.
It doesn't work, but this works:
if (mkgmap:option:test=true) then else highway=* {...} end
Yes
while these don't work (but should?):
if (mkgmap:option:test!=true) then highway=* {...} end
if (!(mkgmap:option:test=true)) then highway=* {...} end
The above shouldn't (and don't) work Ticker

Hi Ticker, I hope that I understand style parsing correctly now. Thanks for advice.
Not sure what you mean.
I'm a programmer. I have some preconception about conditional statement, logical operators etc. Situation, where rules for condition "tag=value" are different than for "tag!=value" is surprising for me. I was aware about some restriction for tests in style, but when I tripped on a problem, I couldn't find a clear explanation in manual. I had to use trial and errors to find a solution. -- Best regards, Andrzej
participants (4)
-
Andrzej Popowski
-
Gerd Petermann
-
Ralf Kleineisel
-
Ticker Berkin