Changeset 4011 in josm


Ignore:
Timestamp:
Mar 30, 2011 10:25:20 PM (2 years ago)
Author:
bastiK
Message:

applied #6150 - mapcss - improve parent_tag (based on patch by Gubaer)

Location:
trunk/src/org/openstreetmap/josm/gui/mappaint
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/mappaint/Environment.java

    r3893 r4011  
    22package org.openstreetmap.josm.gui.mappaint; 
    33 
     4import java.util.Collection; 
     5import java.util.List; 
     6 
    47import org.openstreetmap.josm.data.osm.OsmPrimitive; 
     8import org.openstreetmap.josm.gui.mappaint.mapcss.Instruction; 
    59 
    610public class Environment { 
    7      
     11 
    812    public OsmPrimitive osm; 
    913    public MultiCascade mc; 
    1014    public String layer; 
    1115    public StyleSource source; 
     16 
     17    /** 
     18     * <p>When matching a child selector, the matching referrers will be stored. 
     19     * They can be accessed in {@link Instruction#execute(Environment)} to access 
     20     * tags from parent objects.</p> 
     21     */ 
     22    private List<OsmPrimitive> matchingReferrers = null; 
    1223 
    1324    public Environment(OsmPrimitive osm, MultiCascade mc, String layer, StyleSource source) { 
     
    1829    } 
    1930 
     31    public Collection<OsmPrimitive> getMatchingReferrers() { 
     32        return matchingReferrers; 
     33    } 
     34 
     35    public void setMatchingReferrers(List<OsmPrimitive> refs) { 
     36        matchingReferrers = refs; 
     37    } 
     38 
     39    public void clearMatchingReferrers() { 
     40        matchingReferrers = null; 
     41    } 
    2042} 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Expression.java

    r4008 r4011  
    1717import org.openstreetmap.josm.actions.search.SearchCompiler.ParseError; 
    1818import org.openstreetmap.josm.data.osm.OsmPrimitive; 
    19 import org.openstreetmap.josm.data.osm.Relation; 
    2019import org.openstreetmap.josm.gui.mappaint.Cascade; 
    2120import org.openstreetmap.josm.gui.mappaint.Environment; 
     
    174173            } 
    175174 
    176             // FIXME: respect parent selector chain 
    177175            public String parent_tag(String key) { 
    178                 for (Relation parent: OsmPrimitive.getFilteredList(env.osm.getReferrers(), Relation.class)) { 
    179                     String value = parent.get(key); 
    180                     if (value != null) return value; 
    181                 } 
    182                 return null; 
     176                if (env.getMatchingReferrers() == null) { 
     177                    // we don't have a matched parent, so just search all referrers 
     178                    for (OsmPrimitive parent : env.osm.getReferrers()) { 
     179                        String value = parent.get(key); 
     180                        if (value != null) 
     181                            return value; 
     182                    } 
     183                    return null; 
     184                } 
     185                if (env.getMatchingReferrers().isEmpty()) 
     186                    return null; 
     187                // use always the first matching referrer to have consistency 
     188                // in an expression and declaration block 
     189                return env.getMatchingReferrers().iterator().next().get(key); 
    183190            } 
    184191 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java

    r3987 r4011  
    140140        for (MapCSSRule r : rules) { 
    141141            for (Selector s : r.selectors) { 
    142                 if (s.applies(env)) { 
     142                env.clearMatchingReferrers(); 
     143                if (s.matches(env)) { // as side effect env.matchingReferrers will be set (if s is a child selector) 
    143144                    if (s.getRange().contains(scale)) { 
    144145                        mc.range = Range.cut(mc.range, s.getRange()); 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java

    r3902 r4011  
    22package org.openstreetmap.josm.gui.mappaint.mapcss; 
    33 
     4import java.util.ArrayList; 
    45import java.util.List; 
    56 
     
    1516 
    1617public interface Selector { 
    17      
    18     public boolean applies(Environment e); 
     18 
     19    /** 
     20     * Apply the selector to the primitive and check if it matches. 
     21     * 
     22     * @param env the Environment. env.mc and env.layer are read-only when matching a selector. 
     23     * env.source is not needed. This method will set the matchingReferrers field of env as 
     24     * a side effect! Make sure to clear it before invoking this method. 
     25     * @return true, if the selector applies 
     26     */ 
     27    public boolean matches(Environment env); 
    1928 
    2029    public String getSubpart(); 
     30 
    2131    public Range getRange(); 
    2232 
    23     public static class DescendentSelector implements Selector { 
     33    /** 
     34     * <p>Represents a child selector or a parent selector.</p> 
     35     *  
     36     * <p>In addition to the standard CSS notation for child selectors, JOSM also supports 
     37     * an "inverse" notation:</p> 
     38     * <pre> 
     39     *    selector_a > selector_b { ... }       // the standard notation (child selector) 
     40     *    relation[type=route] > way { ... }    // example (all ways of a route) 
     41     *  
     42     *    selector_a < selector_b { ... }       // the inverse notation (parent selector) 
     43     *    node[traffic_calming] < way { ... }   // example (way that has a traffic calming node) 
     44     * </pre> 
     45     * 
     46     */ 
     47    public static class ChildOrParentSelector implements Selector { 
    2448        Selector a, b; 
    25         boolean child; 
     49        /** true, if this represents a parent selector (otherwise it is a child selector) 
     50         */ 
     51        private final boolean parentSelector; 
    2652 
    27         public DescendentSelector(Selector a, Selector b, boolean child) { 
     53        /** 
     54         *  
     55         * @param a the first selector 
     56         * @param b the second selector 
     57         * @param parentSelector if true, this is a parent selector; otherwise a child selector 
     58         */ 
     59        public ChildOrParentSelector(Selector a, Selector b, boolean parentSelector) { 
    2860            this.a = a; 
    2961            this.b = b; 
    30             this.child = child; 
     62            this.parentSelector = parentSelector; 
    3163        } 
    3264 
    3365        @Override 
    34         public boolean applies(Environment e) { 
    35             if (!b.applies(e)) 
     66        public boolean matches(Environment e) { 
     67            if (!b.matches(e)) 
    3668                return false; 
    3769 
    3870            Environment e2 = new Environment(null, e.mc, e.layer, e.source); 
    39             if (child) { 
    40                 for (OsmPrimitive osm : e.osm.getReferrers()) { 
    41                     e2.osm = osm; 
    42                     if (a.applies(e2)) 
    43                         return true; 
     71            List<OsmPrimitive> matchingRefs = new ArrayList<OsmPrimitive>(); 
     72            if (!parentSelector) { 
     73                for (OsmPrimitive ref : e.osm.getReferrers()) { 
     74                    e2.osm = ref; 
     75                    if (a.matches(e2)) { 
     76                        matchingRefs.add(ref); 
     77                    } 
     78                } 
     79                if (!matchingRefs.isEmpty()) { 
     80                    e.setMatchingReferrers(matchingRefs); 
     81                    return true; 
    4482                } 
    4583            } else { 
     
    4785                    for (OsmPrimitive chld : ((Relation) e.osm).getMemberPrimitives()) { 
    4886                        e2.osm = chld; 
    49                         if (a.applies(e2)) 
     87                        if (a.matches(e2)) 
    5088                            return true; 
    5189                    } 
     
    5391                    for (Node n : ((Way) e.osm).getNodes()) { 
    5492                        e2.osm = n; 
    55                         if (a.applies(e2)) 
     93                        if (a.matches(e2)) 
    5694                            return true; 
    5795                    } 
     
    104142 
    105143        @Override 
    106         public boolean applies(Environment e) { 
     144        public boolean matches(Environment e) { 
    107145            if (!baseApplies(e.osm)) 
    108146                return false; 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParser.java

    r3971 r4011  
    1515import org.openstreetmap.josm.gui.mappaint.mapcss.Expression.FunctionExpression; 
    1616import org.openstreetmap.josm.gui.mappaint.mapcss.Expression.LiteralExpression; 
    17 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.DescendentSelector; 
     17import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.ChildOrParentSelector; 
    1818import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.GeneralSelector; 
    1919import org.openstreetmap.josm.tools.Pair; 
     
    275275 
    276276  final public Selector child_selector() throws ParseException { 
    277     boolean child = false; 
     277    boolean parentSelector = false; 
    278278    Selector sel1, sel2 = null; 
    279279    sel1 = selector(); 
     
    285285      case GREATER: 
    286286        jj_consume_token(GREATER); 
    287                       child = true; 
     287                      parentSelector = false; 
    288288        break; 
    289289      case LESS: 
    290290        jj_consume_token(LESS); 
    291                                                  child = false; 
     291                                                           parentSelector = true; 
    292292        break; 
    293293      default: 
     
    304304      ; 
    305305    } 
    306       {if (true) return sel2 != null ? new DescendentSelector(sel1, sel2, child) : sel1;} 
     306      {if (true) return sel2 != null ? new ChildOrParentSelector(sel1, sel2, parentSelector) : sel1;} 
    307307    throw new Error("Missing return statement in function"); 
    308308  } 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParser.jj

    r3971 r4011  
    2020import org.openstreetmap.josm.gui.mappaint.mapcss.Expression.FunctionExpression; 
    2121import org.openstreetmap.josm.gui.mappaint.mapcss.Expression.LiteralExpression; 
    22 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.DescendentSelector; 
     22import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.ChildOrParentSelector; 
    2323import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.GeneralSelector; 
    2424import org.openstreetmap.josm.tools.Pair; 
     
    251251Selector child_selector() : 
    252252{ 
    253     boolean child = false; 
     253    boolean parentSelector = false; 
    254254    Selector sel1, sel2 = null; 
    255255} 
     
    257257    sel1=selector() w() 
    258258    ( 
    259         ( <GREATER> { child = true; } | <LESS> { child = false; } ) w() 
     259        ( <GREATER> { parentSelector = false; } | <LESS> { parentSelector = true; } ) w() 
    260260        sel2=selector() w() 
    261261    )? 
    262     { return sel2 != null ? new DescendentSelector(sel1, sel2, child) : sel1; } 
     262    { return sel2 != null ? new ChildOrParentSelector(sel1, sel2, parentSelector) : sel1; } 
    263263} 
    264264 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/parser/MapCSSParserTokenManager.java

    r3967 r4011  
    1313import org.openstreetmap.josm.gui.mappaint.mapcss.Expression.FunctionExpression; 
    1414import org.openstreetmap.josm.gui.mappaint.mapcss.Expression.LiteralExpression; 
    15 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.DescendentSelector; 
     15import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.ChildOrParentSelector; 
    1616import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.GeneralSelector; 
    1717import org.openstreetmap.josm.tools.Pair; 
Note: See TracChangeset for help on using the changeset viewer.