Ticket #6150: mapcss-parent_tag-bastiK-version.patch

File mapcss-parent_tag-bastiK-version.patch, 6.6 KB (added by bastiK, 14 years ago)

ideas for improvement, based on the patch by Gubaer

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

     
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.gui.mappaint;
    33
     4import java.util.List;
     5
    46import org.openstreetmap.josm.data.osm.OsmPrimitive;
     7import org.openstreetmap.josm.gui.mappaint.mapcss.Instruction;
     8import org.openstreetmap.josm.gui.mappaint.mapcss.Selector;
    59
    610public class Environment {
    7    
     11
    812    public OsmPrimitive osm;
    913    public MultiCascade mc;
    1014    public String layer;
    1115    public StyleSource source;
     16    /**
     17     * <p>after the selectors of a MapCSS rule have been applied to {@code osm}, the matching
     18     * parent objects of {@code osm} are remembered in this field. It can be accessed in
     19     * {@link Instruction#execute(Environment)} to access tags from parent objects.</p>
     20     *
     21     */
     22    public List<OsmPrimitive> matchingReferrers = null;
    1223
    1324    public Environment(OsmPrimitive osm, MultiCascade mc, String layer, StyleSource source) {
    1425        this.osm = osm;
     
    1728        this.source = source;
    1829    }
    1930
     31    public void setMatchingReferrers(List<OsmPrimitive> refs) {
     32        matchingReferrers = refs;
     33    }
     34
     35    public void forgetMatchingReferrers() {
     36        this.matchingReferrers = null;
     37    }
    2038}
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/Expression.java

     
    1616import org.openstreetmap.josm.actions.search.SearchCompiler.Match;
    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;
    2221import org.openstreetmap.josm.tools.CheckParameterUtil;
     
    173172                return env.osm.get(key);
    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)) {
     176                if (env.matchingReferrers == null) {
     177                    for (OsmPrimitive parent : env.osm.getReferrers()) {
     178                        String value = parent.get(key);
     179                        if (value != null) return value;
     180                    }
     181                    return null;
     182                }
     183                for (OsmPrimitive parent: env.matchingReferrers) {
    179184                    String value = parent.get(key);
    180185                    if (value != null) return value;
    181186                }
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java

     
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.gui.mappaint.mapcss;
    33
     4import java.util.ArrayList;
    45import java.util.List;
    56
    67import org.openstreetmap.josm.data.osm.Node;
     
    1415import org.openstreetmap.josm.tools.Utils;
    1516
    1617public interface Selector {
    17    
     18
    1819    public boolean applies(Environment e);
    1920
    2021    public String getSubpart();
    2122    public Range getRange();
    2223
     24    /**
     25     * <p>Despite its name represents a <em>child selector</em>. JOSM doesn't support
     26     * descendant selectors yet.</p>
     27     *
     28     * <p>In addition to the standard CSS notation for child selectors, JOSM also supports
     29     * an "inverse" notation:</p>
     30     * <pre>
     31     *    // the standard notation:
     32     *    parentselector > childselector { ... }
     33     *
     34     *    // the inverse notation:
     35     *    childselector < parentselector { ... }
     36     * </pre>
     37     *
     38     */
    2339    public static class DescendentSelector implements Selector {
    2440        Selector a, b;
    25         boolean child;
     41        /** true, if this represents a child selector in inverse notation
     42         * {@code childselector < parentselector}
     43         */
     44        boolean inverseNotation;
    2645
     46        /**
     47         *
     48         * @param a the first selector
     49         * @param b the second selector
     50         * @param child if true {@code a} is the child selector; otherwise, {@code a}
     51         * is the parent selector
     52         */
    2753        public DescendentSelector(Selector a, Selector b, boolean child) {
    2854            this.a = a;
    2955            this.b = b;
    30             this.child = child;
     56            this.inverseNotation = !child;
    3157        }
    3258
    3359        @Override
     
    3662                return false;
    3763
    3864            Environment e2 = new Environment(null, e.mc, e.layer, e.source);
    39             if (child) {
     65            List<OsmPrimitive> matchingRefs = new ArrayList<OsmPrimitive>();
     66            if (!inverseNotation) {
     67                boolean foundMatchingReferrer = false;
    4068                for (OsmPrimitive osm : e.osm.getReferrers()) {
    4169                    e2.osm = osm;
    42                     if (a.applies(e2))
    43                         return true;
     70                    if (a.applies(e2)) {
     71                        matchingRefs.add(osm);
     72                        foundMatchingReferrer = true;
     73                    }
    4474                }
     75                if (foundMatchingReferrer) {
     76                    e.setMatchingReferrers(matchingRefs);
     77                    return true;
     78                }
    4579            } else {
    4680                if (e.osm instanceof Relation) {
    4781                    for (OsmPrimitive chld : ((Relation) e.osm).getMemberPrimitives()) {
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java

     
    139139        Environment env = new Environment(osm, mc, null, this);
    140140        for (MapCSSRule r : rules) {
    141141            for (Selector s : r.selectors) {
     142                env.forgetMatchingReferrers();
    142143                if (s.applies(env)) {
    143144                    if (s.getRange().contains(scale)) {
    144145                        mc.range = Range.cut(mc.range, s.getRange());