Ticket #6150: mapcss-text-instruction.2.patch

File mapcss-text-instruction.2.patch, 16.1 KB (added by Gubaer, 15 years ago)

Updated patch

  • src/org/openstreetmap/josm/gui/mappaint/LabelCompositionStrategy.java

     
    4747
    4848    static public class StaticLabelCompositionStrategy extends LabelCompositionStrategy {
    4949        private String defaultLabel;
     50
    5051        public StaticLabelCompositionStrategy(String defaultLabel){
    5152            this.defaultLabel = defaultLabel;
    5253        }
  • src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java

     
    2020import org.openstreetmap.josm.gui.PleaseWaitRunnable;
    2121import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource;
    2222import org.openstreetmap.josm.gui.mappaint.xml.XmlStyleSource;
     23import org.openstreetmap.josm.gui.preferences.MapPaintPreference.MapPaintPrefMigration;
    2324import org.openstreetmap.josm.gui.preferences.SourceEntry;
    24 import org.openstreetmap.josm.gui.preferences.MapPaintPreference.MapPaintPrefMigration;
    2525import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    2626import org.openstreetmap.josm.io.MirroredInputStream;
    2727import org.openstreetmap.josm.tools.ImageProvider;
     
    4141    {
    4242        return styles;
    4343    }
    44    
     44
     45    /**
     46     * Value holder for a reference to a tag name. A style instruction
     47     * <pre>
     48     *    text: a_tag_name;
     49     * </pre>
     50     * results in a tag reference for the tag <tt>a_tag_name</tt> in the
     51     * style cascade.
     52     */
     53    public static class TagKeyReference {
     54        public String key;
     55        public TagKeyReference(String key){
     56            this.key = key;
     57        }
     58
     59        @Override
     60        public String toString() {
     61            return "TagKeyReference{" + "key='" + key + "'}";
     62        }
     63
     64        @Override
     65        public int hashCode() {
     66            final int prime = 31;
     67            int result = 1;
     68            result = prime * result + ((key == null) ? 0 : key.hashCode());
     69            return result;
     70        }
     71
     72        @Override
     73        public boolean equals(Object obj) {
     74            if (this == obj)
     75                return true;
     76            if (obj == null)
     77                return false;
     78            if (getClass() != obj.getClass())
     79                return false;
     80            TagKeyReference other = (TagKeyReference) obj;
     81            if (key == null) {
     82                if (other.key != null)
     83                    return false;
     84            } else if (!key.equals(other.key))
     85                return false;
     86            return true;
     87        }
     88    }
     89
    4590    public static class IconReference {
    4691
    4792        public String iconName;
     
    111156            dirs.add("resource://images/styles/standard/");
    112157            dirs.add("resource://images/styles/");
    113158        }
    114        
     159
    115160        return dirs;
    116161    }
    117162
     
    129174        for (StyleSource source : styles.getStyleSources()) {
    130175            source.loadStyleSource();
    131176        }
    132        
     177
    133178        fireMapPaintSylesUpdated();
    134179    }
    135180
     
    138183        try {
    139184            in = new MirroredInputStream(entry.url);
    140185            InputStream zip = in.getZipEntry("xml", "style");
    141             if (zip != null) {
     186            if (zip != null)
    142187                return new XmlStyleSource(entry);
    143             }
    144188            zip = in.getZipEntry("mapcss", "style");
    145             if (zip != null) {
     189            if (zip != null)
    146190                return new MapCSSStyleSource(entry);
    147             }
    148             if (entry.url.toLowerCase().endsWith(".mapcss")) {
     191            if (entry.url.toLowerCase().endsWith(".mapcss"))
    149192                return new MapCSSStyleSource(entry);
    150             }
    151             if (entry.url.toLowerCase().endsWith(".xml")) {
     193            if (entry.url.toLowerCase().endsWith(".xml"))
    152194                return new XmlStyleSource(entry);
    153             } else {
     195            else {
    154196                InputStreamReader reader = new InputStreamReader(in);
    155197                WHILE: while (true) {
    156198                    int c = reader.read();
    157199                    switch (c) {
    158                         case -1:
    159                             break WHILE;
    160                         case ' ':
    161                         case '\t':
    162                         case '\n':
    163                         case '\r':
    164                             continue;
    165                         case '<':
    166                             return new XmlStyleSource(entry);
    167                         default:
    168                             return new MapCSSStyleSource(entry);
     200                    case -1:
     201                        break WHILE;
     202                    case ' ':
     203                    case '\t':
     204                    case '\n':
     205                    case '\r':
     206                        continue;
     207                    case '<':
     208                        return new XmlStyleSource(entry);
     209                    default:
     210                        return new MapCSSStyleSource(entry);
    169211                    }
    170212                }
    171213                System.err.println("Warning: Could not detect style type. Using default (xml).");
     
    271313        int[] selSorted = Arrays.copyOf(sel, sel.length);
    272314        Arrays.sort(selSorted);
    273315
    274         if (i < 0) { // Up
     316        if (i < 0)
    275317            return selSorted[0] >= -i;
    276         } else
    277         if (i > 0) { // Down
    278             return selSorted[selSorted.length-1] <= styles.getStyleSources().size() - 1 - i;
    279         } else
    280             return true;
     318            else
     319                if (i > 0)
     320                    return selSorted[selSorted.length-1] <= styles.getStyleSources().size() - 1 - i;
     321                else
     322                    return true;
    281323    }
    282324
    283325    public static void toggleStyleActive(int... sel) {
     
    319361    }
    320362
    321363    protected static final CopyOnWriteArrayList<MapPaintSylesUpdateListener> listeners
    322             = new CopyOnWriteArrayList<MapPaintSylesUpdateListener>();
     364    = new CopyOnWriteArrayList<MapPaintSylesUpdateListener>();
    323365
    324366    public static void addMapPaintSylesUpdateListener(MapPaintSylesUpdateListener listener) {
    325367        if (listener != null) {
  • src/org/openstreetmap/josm/gui/mappaint/TextElement.java

     
    88
    99import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1010import org.openstreetmap.josm.gui.mappaint.LabelCompositionStrategy.DeriveLabelFromNameTagsCompositionStrategy;
     11import org.openstreetmap.josm.gui.mappaint.LabelCompositionStrategy.StaticLabelCompositionStrategy;
    1112import org.openstreetmap.josm.gui.mappaint.LabelCompositionStrategy.TagLookupCompositionStrategy;
     13import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.TagKeyReference;
    1214import org.openstreetmap.josm.tools.CheckParameterUtil;
    1315import org.openstreetmap.josm.tools.Utils;
    1416
     
    8082     * @return the label composition strategy
    8183     */
    8284    protected static LabelCompositionStrategy buildLabelCompositionStrategy(Cascade c, boolean defaultAnnotate){
    83         Keyword textKW = c.get("text", null, Keyword.class, true);
    84         if (textKW == null) {
    85             String textKey = c.get("text", null, String.class);
    86             if (textKey == null)
    87                 return defaultAnnotate ? AUTO_LABEL_COMPOSITION_STRATEGY : null;
    88             return new TagLookupCompositionStrategy(textKey);
    89         } else if (textKW.val.equals("auto"))
    90             return AUTO_LABEL_COMPOSITION_STRATEGY;
    91         else
    92             return new TagLookupCompositionStrategy(textKW.val);
     85        /*
     86         * If the cascade includes a TagKeyReference we will lookup the rendered label
     87         * from a tag value.
     88         */
     89        TagKeyReference tkr = c.get("text", null, TagKeyReference.class, true);
     90        if (tkr != null)
     91            return new TagLookupCompositionStrategy(tkr.key);
     92
     93        /*
     94         * Check whether the label composition strategy is given by
     95         * a keyword
     96         */
     97        Keyword keyword = c.get("text", null, Keyword.class, true);
     98        if (keyword != null){
     99            if (keyword.equals(Keyword.AUTO))
     100                return AUTO_LABEL_COMPOSITION_STRATEGY;
     101            return null; // unsupported keyword
     102        }
     103
     104        /*
     105         * Do we have a static text label?
     106         */
     107        String text = c.get("text", null, String.class, true);
     108        if (text != null)
     109            return new StaticLabelCompositionStrategy(text);
     110        return defaultAnnotate ? AUTO_LABEL_COMPOSITION_STRATEGY : null;
    93111    }
    94112
    95113    /**
     
    183201            return false;
    184202        final TextElement other = (TextElement) obj;
    185203        return  equal(labelCompositionStrategy, other.labelCompositionStrategy) &&
    186                 equal(font, other.font) &&
    187                 xOffset == other.xOffset &&
    188                 yOffset == other.yOffset &&
    189                 equal(color, other.color) &&
    190                 equal(haloRadius, other.haloRadius) &&
    191                 equal(haloColor, other.haloColor);
     204        equal(font, other.font) &&
     205        xOffset == other.xOffset &&
     206        yOffset == other.yOffset &&
     207        equal(color, other.color) &&
     208        equal(haloRadius, other.haloRadius) &&
     209        equal(haloColor, other.haloColor);
    192210    }
    193211}
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/Expression.java

     
    1515import org.openstreetmap.josm.actions.search.SearchCompiler;
    1616import org.openstreetmap.josm.actions.search.SearchCompiler.Match;
    1717import org.openstreetmap.josm.actions.search.SearchCompiler.ParseError;
     18import org.openstreetmap.josm.data.osm.OsmPrimitive;
     19import org.openstreetmap.josm.data.osm.Relation;
    1820import org.openstreetmap.josm.gui.mappaint.Cascade;
    1921import org.openstreetmap.josm.gui.mappaint.Environment;
    2022import org.openstreetmap.josm.tools.Utils;
    2123
    2224public interface Expression {
    23 
    2425    public Object evaluate(Environment env);
    2526
    2627    public static class LiteralExpression implements Expression {
     
    4647    }
    4748
    4849    public static class FunctionExpression implements Expression {
     50        //static Logger logger = Logger.getLogger(FunctionExpression.class.getName());
     51
    4952        String name;
    5053        List<Expression> args;
    5154
     
    7275            public Float minus(float... args) {
    7376                if (args.length == 0)
    7477                    return 0f;
    75                 if (args.length == 1) { // unary minus
     78                if (args.length == 1)
    7679                    return -args[0];
    77                 }
    7880                float res = args[0];
    7981                for (int i=1; i<args.length; ++i) {
    8082                    res -= args[i];
     
    163165                return env.osm.get(key);
    164166            }
    165167
     168            public String tag(String key) {
     169                return get_tag_value(key);
     170            }
     171
     172            public String text(String value){
     173                return value;
     174            }
     175
     176            /**
     177             * <p>Replies the value of a tag with name <tt>key</tt> provided by one of the parent
     178             * relations of the OSM object in the environment, or null, if no such tag exists.</p>
     179             *
     180             * @param key the tag key
     181             * @return the tag value
     182             */
     183            public String parent_tag(String key) {
     184                for (Relation parent: OsmPrimitive.getFilteredList(env.osm.getReferrers(), Relation.class)) {
     185                    String value = parent.get(key);
     186                    if (value != null) return value;
     187                }
     188                return null;
     189            }
     190
    166191            public boolean has_tag_key(String key) {
    167192                return env.osm.hasKey(key);
    168193            }
     
    285310                throw  new RuntimeException(ex);
    286311            }
    287312            for (Method m : allMethods) {
    288                 if (!m.getName().equals(name))
     313                if (!m.getName().equals(name)) {
    289314                    continue;
     315                }
    290316                Class<?>[] expectedParameterTypes = m.getParameterTypes();
    291317                Object[] convertedArgs = new Object[expectedParameterTypes.length];
    292318
     
    303329                    }
    304330                    convertedArgs[0] = arrayArg;
    305331                } else {
    306                     if (args.size() != expectedParameterTypes.length)
     332                    if (args.size() != expectedParameterTypes.length) {
    307333                        continue;
     334                    }
    308335                    for (int i=0; i<args.size(); ++i) {
    309336                        convertedArgs[i] = Cascade.convertTo(args.get(i).evaluate(env), expectedParameterTypes[i]);
    310337                        if (convertedArgs[i] == null)
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/Instruction.java

     
    44import java.util.Arrays;
    55
    66import org.openstreetmap.josm.gui.mappaint.Environment;
     7import org.openstreetmap.josm.gui.mappaint.Keyword;
     8import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
    79import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.IconReference;
    810
    911abstract public class Instruction {
     
    2426    }
    2527
    2628    public static class AssignmentInstruction extends Instruction {
     29        //static private final Logger logger = Logger.getLogger(AssignmentInstruction.class.getName());
    2730        String key;
    2831        Object val;
    2932
    3033        public AssignmentInstruction(String key, Object val) {
    3134            this.key = key;
    3235            if (val instanceof Expression.LiteralExpression) {
    33                 this.val = ((Expression.LiteralExpression) val).evaluate(null);
     36                if (key.equals("text")) {
     37                    /* Special case for declaration 'text: ...'
     38                     *
     39                     * - Treat the value 'auto' as keyword.
     40                     * - Treat any other literal value 'litval' as as reference to tag with key 'litval'
     41                     *
     42                     * - Accept function expressions as is. This allows for
     43                     *     tag(a_tag_name)                 value of a tag
     44                     *     text("a static text")           a static text
     45                     *     parent_tag(a_tag_name)          value of a tag of a parent relation
     46                     */
     47                    Object value = ((Expression.LiteralExpression) val).evaluate(null);
     48                    if (value != null){
     49                        if (value.equals(Keyword.AUTO)) {
     50                            this.val = Keyword.AUTO;
     51                        } else {
     52                            this.val = new MapPaintStyles.TagKeyReference(value.toString());
     53                        }
     54                    }
     55                } else {
     56                    this.val = ((Expression.LiteralExpression) val).evaluate(null);
     57                }
    3458            } else {
    3559                this.val = val;
    3660            }
     
    3862
    3963        @Override
    4064        public void execute(Environment env) {
    41             Object value = (val instanceof Expression) ? ((Expression) val).evaluate(env) : val;
     65            Object value = null;
     66            if (val instanceof Expression) {
     67                value = ((Expression) val).evaluate(env);
     68            } else {
     69                value = val;
     70            }
    4271            if (key.equals("icon-image") || key.equals("fill-image")) {
    4372                if (value instanceof String) {
    4473                    value = new IconReference((String) value, env.source);