Ticket #9667: 9667.patch

File 9667.patch, 7.5 KB (added by simon04, 10 years ago)
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java

    diff --git a/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java b/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java
    index 6ad8b47..49fb4f2 100644
    a b public final class ExpressionFactory {  
    321321            return env.parent.get(key);
    322322        }
    323323
     324        public String child_tag(String key) {
     325            return env.child == null ? null : env.child.get(key);
     326        }
     327
    324328        /**
    325329         * Determines whether the object has a tag with the given key.
    326330         */
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj

    diff --git a/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj b/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj
    index c777eef..36026a4 100644
    a b Selector child_selector() :  
    276276    selLeft=selector() w()
    277277    (
    278278        (
    279             ( <GREATER> { type = Selector.ChildOrParentSelectorType.CHILD; } | <LESS> { type = Selector.ChildOrParentSelectorType.PARENT; } )
     279            (
     280                <GREATER> { type = Selector.ChildOrParentSelectorType.CHILD; }
     281            |
     282                <LESS> { type = Selector.ChildOrParentSelectorType.PARENT; }
     283            |
     284                <PLUS> { type = Selector.ChildOrParentSelectorType.SIBLING; }
     285            )
    280286            ( ( c=condition(Context.LINK) | c=class_or_pseudoclass(Context.LINK) ) { conditions.add(c); } )*
    281287        |
    282288            <ELEMENT_OF> { type = Selector.ChildOrParentSelectorType.ELEMENT_OF; }
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java

    diff --git a/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java b/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
    index 7239dfa..3bff3e7 100644
    a b public interface Selector {  
    3838    public Range getRange();
    3939
    4040    public static enum ChildOrParentSelectorType {
    41         CHILD, PARENT, ELEMENT_OF, CROSSING
     41        CHILD, PARENT, ELEMENT_OF, CROSSING, SIBLING
    4242    }
    4343
    4444    /**
    public interface Selector {  
    257257                    crossingFinder.visit(e.osm.getDataSet().searchWays(e.osm.getBBox()));
    258258                }
    259259                return e.child != null;
     260            } else if (ChildOrParentSelectorType.SIBLING.equals(type)) {
     261                if (e.osm instanceof Node) {
     262                    for (Way w : Utils.filteredCollection(e.osm.getReferrers(), Way.class)) {
     263                        final int i = w.getNodes().indexOf(e.osm);
     264                        if (i - 1 >= 0) {
     265                            final Node n = w.getNode(i - 1);
     266                            final Environment e2 = e.withPrimitive(n).withParent(w).withChild(e.osm);
     267                            if (left.matches(e2)) {
     268                                if (link.matches(e2.withLinkContext())) {
     269                                    e.child = n;
     270                                    e.index = i;
     271                                    e.parent = w;
     272                                    return true;
     273                                }
     274                            }
     275                        }
     276                    }
     277                }
    260278            } else if (ChildOrParentSelectorType.CHILD.equals(type)) {
    261279                MatchingReferrerFinder collector = new MatchingReferrerFinder(e);
    262280                e.osm.visitReferrers(collector);
  • test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.groovy

    diff --git a/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.groovy b/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.groovy
    index b089b7c..a1307b1 100644
    a b import org.junit.Before  
    44import org.junit.Test
    55import org.openstreetmap.TestUtils
    66import org.openstreetmap.josm.Main
    7 import org.openstreetmap.josm.data.Preferences
     7import org.openstreetmap.josm.data.coor.LatLon
     8import org.openstreetmap.josm.data.osm.DataSet
    89import org.openstreetmap.josm.data.osm.OsmPrimitive
    910import org.openstreetmap.josm.data.osm.Way
     11import org.openstreetmap.josm.data.projection.Projections
    1012import org.openstreetmap.josm.gui.mappaint.Environment
    1113import org.openstreetmap.josm.gui.mappaint.MultiCascade
    1214import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.MapCSSParser
    1315import org.openstreetmap.josm.tools.ColorHelper
    14 import org.openstreetmap.josm.tools.Utils
    1516
    1617import java.awt.Color
    1718
    class MapCSSParserTest {  
    3334
    3435    @Before
    3536    public void setUp() throws Exception {
    36         Main.pref = new Preferences()
     37        Main.initApplicationPreferences()
     38        Main.setProjection(Projections.getProjectionByCode("EPSG:3857"));
    3739    }
    3840
    3941    @Test
    class MapCSSParserTest {  
    240242    public void testColorParsing() throws Exception {
    241243        assert ColorHelper.html2color("#12345678") == new Color(0x12, 0x34, 0x56, 0x78)
    242244    }
     245
     246    @Test
     247    public void testSiblingSelector() throws Exception {
     248        def s1 = (Selector.ChildOrParentSelector) getParser("*[a?][parent_tag(\"highway\")=\"unclassified\"] + *[b?]").child_selector()
     249        def ds = new DataSet()
     250        def n1 = new org.openstreetmap.josm.data.osm.Node(new LatLon(1, 2))
     251        n1.put("a", "true")
     252        def n2 = new org.openstreetmap.josm.data.osm.Node(new LatLon(1.1, 2.2))
     253        n2.put("b", "true")
     254        def w = new Way()
     255        w.put("highway", "unclassified")
     256        ds.addPrimitive(n1)
     257        ds.addPrimitive(n2)
     258        ds.addPrimitive(w)
     259        w.addNode(n1)
     260        w.addNode(n2)
     261
     262        def e = new Environment().withPrimitive(n2)
     263        assert s1.matches(e)
     264        assert e.osm == n2
     265        assert e.child == n1
     266        assert e.parent == w
     267        assert !s1.matches(new Environment().withPrimitive(n1))
     268        assert !s1.matches(new Environment().withPrimitive(w))
     269    }
     270
     271    @Test
     272    public void testSiblingSelectorInterpolation() throws Exception {
     273        def s1 = (Selector.ChildOrParentSelector) getParser(
     274                "*[tag(\"addr:housenumber\") > child_tag(\"addr:housenumber\")][regexp_test(\"even|odd\", parent_tag(\"addr:interpolation\"))]" +
     275                        " + *[addr:housenumber]").child_selector()
     276        def ds = new DataSet()
     277        def n1 = new org.openstreetmap.josm.data.osm.Node(new LatLon(1, 2))
     278        n1.put("addr:housenumber", "10")
     279        def n2 = new org.openstreetmap.josm.data.osm.Node(new LatLon(1.1, 2.2))
     280        n2.put("addr:housenumber", "100")
     281        def n3 = new org.openstreetmap.josm.data.osm.Node(new LatLon(1.2, 2.3))
     282        n3.put("addr:housenumber", "20")
     283        def w = new Way()
     284        w.put("addr:interpolation", "even")
     285        ds.addPrimitive(n1)
     286        ds.addPrimitive(n2)
     287        ds.addPrimitive(n3)
     288        ds.addPrimitive(w)
     289        w.addNode(n1)
     290        w.addNode(n2)
     291        w.addNode(n3)
     292
     293        assert s1.right.matches(new Environment().withPrimitive(n3))
     294        assert s1.left.matches(new Environment().withPrimitive(n2).withChild(n3).withParent(w))
     295        assert s1.matches(new Environment().withPrimitive(n3))
     296        assert !s1.matches(new Environment().withPrimitive(n1))
     297        assert !s1.matches(new Environment().withPrimitive(n2))
     298        assert !s1.matches(new Environment().withPrimitive(w))
     299    }
    243300}