Index: /home/tms/maps/mkgmap/trunk/src/uk/me/parabola/mkgmap/osmstyle/eval/ExpressionReader.java =================================================================== --- /home/tms/maps/mkgmap/trunk/src/uk/me/parabola/mkgmap/osmstyle/eval/ExpressionReader.java (revision 1020) +++ /home/tms/maps/mkgmap/trunk/src/uk/me/parabola/mkgmap/osmstyle/eval/ExpressionReader.java (working copy) @@ -2,12 +2,12 @@ import java.util.Stack; -import uk.me.parabola.log.Logger; import static uk.me.parabola.mkgmap.osmstyle.eval.Op.CLOSE_PAREN; import static uk.me.parabola.mkgmap.osmstyle.eval.Op.EQUALS; import static uk.me.parabola.mkgmap.osmstyle.eval.Op.NOT_EQUALS; import static uk.me.parabola.mkgmap.osmstyle.eval.Op.OPEN_PAREN; import static uk.me.parabola.mkgmap.osmstyle.eval.Op.VALUE; +import uk.me.parabola.log.Logger; import uk.me.parabola.mkgmap.scan.TokenScanner; /** @@ -35,7 +35,7 @@ break; String val = scanner.nextWord(); - if ("&|!=~()><".contains(val)) + if ("&|!=~()><".contains(val)) saveOp(val); else pushValue(val); @@ -46,6 +46,9 @@ runOp(); // The stack should contain one entry which is the complete tree + if (stack.size() != 1) { + throw new SyntaxException(scanner, "Stack size is "+stack.size()); + } assert stack.size() == 1; return stack.pop(); } @@ -102,7 +105,7 @@ log.debug("convert to NOT EXISTS"); op = new NotExistsOp(); op.setFirst(arg1); - } + } } stack.push(op); } Index: /home/tms/maps/mkgmap/trunk/src/uk/me/parabola/mkgmap/osmstyle/actions/PrependFilter.java =================================================================== --- /home/tms/maps/mkgmap/trunk/src/uk/me/parabola/mkgmap/osmstyle/actions/PrependFilter.java (revision 0) +++ /home/tms/maps/mkgmap/trunk/src/uk/me/parabola/mkgmap/osmstyle/actions/PrependFilter.java (revision 0) @@ -0,0 +1,76 @@ +/* + * Copyright 2009 Toby Speight + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +package uk.me.parabola.mkgmap.osmstyle.actions; + +import java.util.HashMap; +import java.util.Map; + + +/** + * Prepend a Garmin magic-character to the value. + * TODO: symbolic names? + * + * @author Toby Speight + */ +public class PrependFilter extends ValueFilter { + private final String prefix; + + // TODO: runtime select appropriate table + private Mapsymbols = symbols_8bit; + + private static final Map symbols_6bit; + private static final Map symbols_8bit; + + static { + // Firstly, the symbols common to both encodings + symbols_6bit = new HashMap(); + symbols_6bit.put("ele", "\u001f"); // name.height separator + + // Copy to other encoding + symbols_8bit = new HashMap(symbols_6bit); + + // Now add other symbols + symbols_6bit.put("interstate", "\u002a"); // US Interstate + symbols_8bit.put("interstate", "\u0001"); + symbols_6bit.put("shield", "\u002b"); // US Highway shield + symbols_8bit.put("shield", "\u0002"); + symbols_6bit.put("round", "\u002c"); // US Highway round + symbols_8bit.put("round", "\u0003"); + symbols_6bit.put("boxx", "\u002d"); // box with horizontal bands + symbols_8bit.put("boxx", "\u0004"); + symbols_6bit.put("box", "\u002e"); // Square box + symbols_8bit.put("box", "\u0005"); + symbols_6bit.put("oval", "\u002f"); // box with rounded ends + symbols_8bit.put("oval", "\u0006"); + } + + public PrependFilter(String s) { + // First, try the lookup table + String p = symbols.get(s); + if (p == null) { + // else, s is a hex constant character number + try { + p = Character.toString((char)Integer.parseInt(s, 16)); + } catch (NumberFormatException e) { + // failed - use string literally + p = s; + } + } + prefix = p; + } + + public String doFilter(String value) { + return value == null ? null : prefix + value; + } +} Index: /home/tms/maps/mkgmap/trunk/src/uk/me/parabola/mkgmap/osmstyle/actions/HeightFilter.java =================================================================== --- /home/tms/maps/mkgmap/trunk/src/uk/me/parabola/mkgmap/osmstyle/actions/HeightFilter.java (revision 0) +++ /home/tms/maps/mkgmap/trunk/src/uk/me/parabola/mkgmap/osmstyle/actions/HeightFilter.java (revision 0) @@ -0,0 +1,35 @@ +/* + * Copyright 2009 Toby Speight + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +package uk.me.parabola.mkgmap.osmstyle.actions; + +/** + * A HeightFilter transforms values into Garmin-tagged elevations. + * + * @author Toby Speight + * + * @since 2009-04-26 + */ +public class HeightFilter extends ConvertFilter { + + public HeightFilter(String s) { + super(s); + } + + public String doFilter(String value) { + String s = super.doFilter(value); + if (s != null) + s = "\u001f" + s; + return s; + } +} Index: /home/tms/maps/mkgmap/trunk/src/uk/me/parabola/mkgmap/osmstyle/actions/SubstitutionFilter.java =================================================================== --- /home/tms/maps/mkgmap/trunk/src/uk/me/parabola/mkgmap/osmstyle/actions/SubstitutionFilter.java (revision 0) +++ /home/tms/maps/mkgmap/trunk/src/uk/me/parabola/mkgmap/osmstyle/actions/SubstitutionFilter.java (revision 0) @@ -0,0 +1,42 @@ +/* + * Copyright 2009 Toby Speight + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +package uk.me.parabola.mkgmap.osmstyle.actions; + +/** + * Perform simple string substition on a value. + * + * @author Toby Speight + */ +public class SubstitutionFilter extends ValueFilter { + private final String from; + private final String to; + + public SubstitutionFilter(String arg) { + int i = arg.indexOf("=>"); + if (i >= 0) { + from = arg.substring(0, i); + to = arg.substring(i + 2); + } else { + from = arg; + to = ""; + } + } + + public String doFilter(String value) { + if (value == null) return null; + if (from == null || to == null) + // can't happen! + return value; + return value.replace(from, to); + } +} Index: /home/tms/maps/mkgmap/trunk/src/uk/me/parabola/mkgmap/osmstyle/actions/ValueBuilder.java =================================================================== --- /home/tms/maps/mkgmap/trunk/src/uk/me/parabola/mkgmap/osmstyle/actions/ValueBuilder.java (revision 1020) +++ /home/tms/maps/mkgmap/trunk/src/uk/me/parabola/mkgmap/osmstyle/actions/ValueBuilder.java (working copy) @@ -1,16 +1,16 @@ /* * Copyright (C) 2008 Steve Ratcliffe - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * + * + * * Author: Steve Ratcliffe * Create date: 02-Dec-2008 */ @@ -27,6 +27,7 @@ * Build a value that can have tag values substituted in it. * * @author Steve Ratcliffe + * @author Toby Speight */ public class ValueBuilder { @@ -92,20 +93,21 @@ switch (state) { case 0: if (c == '$') { - if (text.length() > 0) { - items.add(new ValueItem(text.toString())); - text.setLength(0); - } state = 1; } else text.append(c); break; case 1: if (c == '{') { + if (text.length() > 0) { + items.add(new ValueItem(text.toString())); + text.setLength(0); + } tagname = new StringBuilder(); state = 2; } else { state = 0; + text.append('$'); text.append(c); } break; @@ -154,6 +156,14 @@ item.addFilter(new DefaultFilter(arg)); } else if (cmd.equals("conv")) { item.addFilter(new ConvertFilter(arg)); + } else if (cmd.equals("subst")) { + item.addFilter(new SubstitutionFilter(arg)); + } else if (cmd.equals("prefix")) { + item.addFilter(new PrependFilter(arg)); + } else if (cmd.equals("highway-symbol")) { + item.addFilter(new HighwaySymbolFilter(arg)); + } else if (cmd.equals("height")) { + item.addFilter(new HeightFilter(arg)); } } Index: /home/tms/maps/mkgmap/trunk/src/uk/me/parabola/mkgmap/osmstyle/actions/HighwaySymbolFilter.java =================================================================== --- /home/tms/maps/mkgmap/trunk/src/uk/me/parabola/mkgmap/osmstyle/actions/HighwaySymbolFilter.java (revision 0) +++ /home/tms/maps/mkgmap/trunk/src/uk/me/parabola/mkgmap/osmstyle/actions/HighwaySymbolFilter.java (revision 0) @@ -0,0 +1,71 @@ +/* + * Copyright 2009 Toby Speight + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +package uk.me.parabola.mkgmap.osmstyle.actions; + +import java.util.HashMap; +import java.util.Map; + + +/** + * Prepend a Garmin magic-character to the value. + * TODO: symbolic names? + * + * @author Toby Speight + */ +public class HighwaySymbolFilter extends ValueFilter { + private final String prefix; + + private static final Mapsymbols = new HashMap(); + private static final int MAX_REF_LENGTH = 8; // enough for "A6144(M)" (RIP) + + static { + //symbols.put("ele", "\u001f"); // name.height separator + + // Now add other symbols + symbols.put("interstate", "\u0001"); // US Interstate + symbols.put("shield", "\u0002"); // US Highway shield + symbols.put("round", "\u0003"); // US Highway round + symbols.put("hbox", "\u0004"); // box with horizontal bands + symbols.put("box", "\u0005"); // Square box + symbols.put("oval", "\u0006"); // box with rounded ends + } + + public HighwaySymbolFilter(String s) { + // First, try the lookup table + String p = symbols.get(s); + if (p == null) { + p = "[" + s + "]"; + } + prefix = p; + } + + public String doFilter(String value) { + if (value == null || value.length() > MAX_REF_LENGTH) return value; + + // is it mostly alphabetic? + int alpha_balance = 0; + for (char c : value.toCharArray()) { + alpha_balance += (Character.isLetter(c)) ? 1 : -1; + } + if (alpha_balance > 0) return value; + + // remove space if there is exactly one + int first_space = value.indexOf(" "); + if (first_space >= 0 && value.indexOf(" ", first_space) < 0) { + value = value.replace(" ", ""); + } + + return prefix + value; + } +} Index: /home/tms/maps/mkgmap/trunk/resources/styles/default/lines =================================================================== --- /home/tms/maps/mkgmap/trunk/resources/styles/default/lines (revision 1020) +++ /home/tms/maps/mkgmap/trunk/resources/styles/default/lines (working copy) @@ -8,6 +8,13 @@ { name '${ele|conv:m=>ft}'; } [0x21 resolution 20] +# Set highway names to include the reference if there is one +highway=motorway {name '${ref|highway-symbol:hbox} ${name}' | '${ref|highway-symbol:hbox}' | '${name}' } +highway=trunk {name '${ref|highway-symbol:hbox} ${name}' | '${ref|highway-symbol:hbox}' | '${name}' } +highway=primary {name '${ref|highway-symbol:box} ${name}' | '${ref|highway-symbol:box}' | '${name}' } +highway=secondary {name '${ref|highway-symbol:oval} ${name}' | '${ref|highway-symbol:oval}' | '${name}' } +highway=* {name '${ref} ${name}' | '${ref}' | '${name}' } + junction=roundabout & highway=trunk [0x0c road_class=3 road_speed=5 resolution 16] junction=roundabout & highway=primary [0x0c road_class=3 road_speed=4 resolution 19] junction=roundabout & highway=secondary [0x0c road_class=2 road_speed=3 resolution 20] @@ -15,8 +22,6 @@ junction=roundabout & highway=unclassified [0x0c road_class=1 road_speed=2 resolution 21] junction=roundabout [0x0c road_class=0 road_speed=1 resolution 21] -# Set highway names to include the reference if there is one -#highway=* {name '${name} (${ref})' | '${ref}' | '${name}' } highway=bridleway {add access = no; add bicycle = yes; add foot = yes} [0x16 road_class=0 road_speed=0 resolution 23] highway=byway [0x16 road_class=0 road_speed=0 resolution 23] highway=cycleway {add access = no; add bicycle = yes; add foot = yes} [0x16 road_class=0 road_speed=1 resolution 23] Index: /home/tms/maps/mkgmap/trunk/resources/styles/default/points =================================================================== --- /home/tms/maps/mkgmap/trunk/resources/styles/default/points (revision 1020) +++ /home/tms/maps/mkgmap/trunk/resources/styles/default/points (working copy) @@ -99,9 +99,10 @@ # Edge 705 displays 0x650a,0x6511,0x6512,0x6513 as hollow white circles, no menu natural=beach [0x6604 resolution 21] +natural=cave_entrance [0x6601 resolution 19] natural=cliff [0x6607 resolution 21] natural=glacier [0x650a resolution 21] -natural=peak [0x6616 resolution 21] +natural=peak {name '${name|def:}${ele|height:m=>ft|def:}' } [0x6616 resolution 18] natural=spring [0x6511 resolution 21] #natural=stream [0x6512 resolution 21] natural=volcano [0x2c0c resolution 21]