Hi Minko

This rule does not work:
highway ~ 
'(secondary|tertiary|unclassified|residential|minor|living_street|service)'
& oneway=*
& (cycleway=opposite | cycleway=opposite_lane | cycleway=opposite_track | 
oneway:bicycle=no | bicycle:oneway=no )
{set bicycle=no; set mkgmap:cycleway=yes}

I have a fix for this problem attached.

..Steve
Index: src/uk/me/parabola/mkgmap/osmstyle/RuleFileReader.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/RuleFileReader.java	(revision 3133)
+++ src/uk/me/parabola/mkgmap/osmstyle/RuleFileReader.java	(revision )
@@ -278,9 +278,22 @@
 			rearrangeExpression(op.getSecond());
 
 			swapForSelectivity((BinaryOp) op);
+
+			// Rearrange ((A&B)&C) to (A&(B&C)).
+			// This keeps the first term as simple as possible, so that
+			while (op.getFirst().isType(AND)) {
+				Op aAndB = op.getFirst();
+				Op c = op.getSecond();
+				op.setFirst(aAndB.getFirst()); // A
+
+				aAndB.setFirst(aAndB.getSecond());
+				((BinaryOp) aAndB).setSecond(c);  // a-and-b is now b-and-c
+				((BinaryOp) op).setSecond(aAndB);
+			}
+
 			Op op1 = op.getFirst();
 			Op op2 = op.getSecond();
-			
+
 			// If the first term is an EQUALS or EXISTS then this subtree is
 			// already solved and we need to do no more.
 			if (isSolved(op1)) {
Index: test/uk/me/parabola/mkgmap/osmstyle/RuleFileReaderTest.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- test/uk/me/parabola/mkgmap/osmstyle/RuleFileReaderTest.java	(revision 3133)
+++ test/uk/me/parabola/mkgmap/osmstyle/RuleFileReaderTest.java	(revision )
@@ -378,6 +378,27 @@
 	}
 
 	/**
+	 * Failure of the optimiser to promote the correct term to the front.
+	 * Example from mailing list.
+	 */
+	@Test
+	public void testOptimizeFail() {
+		String s = "highway ~ '(secondary|tertiary|unclassified|residential|minor|living_street|service)' " +
+				"& oneway=* " +
+				"& (cycleway=opposite | cycleway=opposite_lane | cycleway=opposite_track )" +
+				"[0x2 ]";
+		RuleSet rs = makeRuleSet(s);
+		Element el = new Way(1);
+		el.addTag("highway", "tertiary");
+		el.addTag("oneway", "1");
+		el.addTag("cycleway", "opposite_track");
+
+		GType type = getFirstType(rs, el);
+		assertNotNull(type);
+		assertEquals(2, type.getType());
+	}
+
+	/**
 	 * This simply is to make sure that actions that affect their own
 	 * conditions do not hang. There are no defined semantics for this.
 	 */
@@ -596,7 +617,7 @@
 		Way el = new Way(1);
 		el.addTag("highway", "primary");
 
-		final List<GType> list = new ArrayList<GType>();
+		final List<GType> list = new ArrayList<>();
 
 		rs.resolveType(el, new TypeResult() {
 			public void add(Element el, GType type) {
@@ -865,16 +886,13 @@
 		assertNotNull(type);
 	}
 
-	@Test
+	@Test(expected = SyntaxException.class)
 	public void testFunctionWithParameters() {
 		// a parameter in a function is not allowed yet
-		try {
-			// this should throw a SyntaxException
-			makeRuleSet("A=B & length(a) > 91 [0x5]");
-			assertTrue("Function with parameters are not allowed", false);
+		// this should throw a SyntaxException
+		makeRuleSet("A=B & length(a) > 91 [0x5]");
+		assertTrue("Function with parameters are not allowed", false);
-		} catch (SyntaxException exp) {
-		}
+	}
-	}
 	
 	@Test
 	public void testIsClosedFunction() {
@@ -1047,7 +1065,7 @@
 	 * resolved type.
 	 */
 	private GType getFirstType(Rule rs, Element el) {
-		final List<GType> types = new ArrayList<GType>();
+		final List<GType> types = new ArrayList<>();
 		rs.resolveType(el, new TypeResult() {
 			public void add(Element el, GType type) {
 				types.add(type);
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Reply via email to