Index: uk/me/parabola/imgfmt/app/Coord.java
===================================================================
--- uk/me/parabola/imgfmt/app/Coord.java	(revision 2889)
+++ uk/me/parabola/imgfmt/app/Coord.java	(working copy)
@@ -40,6 +40,7 @@
 	private final static byte REPLACED_MASK = 0x04;  // bit in flags is true if point was replaced 
 	private final static byte TREAT_AS_NODE_MASK = 0x08; // bit in flags is true if point should be treated as a node
 	private final static byte FIXME_NODE_MASK = 0x10; // bit in flags is true if a node with this coords has a fixme tag
+	private final static byte VIA_NODE_MASK = 0x40; // bit in flags is true if a node with this coords is the via node of a restriction
 	private final int latitude;
 	private final int longitude;
 	private byte highwayCount; // number of highways that use this point
@@ -164,6 +165,21 @@
 			this.flags &= ~FIXME_NODE_MASK; 
 	}
 	
+	/**
+	 * Does this coordinate belong to a via node of a restriction relation?
+	 * @return
+	 */
+	public boolean isViaNodeOfRestriction() {
+		return (flags & VIA_NODE_MASK) != 0;
+	}
+	
+	public void setViaNodeOfRestriction(boolean b) {
+		if (b) 
+			this.flags |= VIA_NODE_MASK;
+		else 
+			this.flags &= ~VIA_NODE_MASK; 
+	}
+	
 	public int hashCode() {
 		// Use a factor for latitude to span over the whole integer range:
 		// max lat: 4194304
Index: uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
===================================================================
--- uk/me/parabola/mkgmap/osmstyle/StyledConverter.java	(revision 2889)
+++ uk/me/parabola/mkgmap/osmstyle/StyledConverter.java	(working copy)
@@ -460,7 +460,9 @@
 				List<RestrictionRelation> lrr = restrictions.get(rr.getViaCoord());
 				if(lrr == null) {
 					lrr = new ArrayList<RestrictionRelation>();
-					restrictions.put(rr.getViaCoord(), lrr);
+					Coord via = rr.getViaCoord();
+					via.setViaNodeOfRestriction(true);
+					restrictions.put(via, lrr);
 				}
 				lrr.add(rr);
 			}
@@ -724,6 +726,8 @@
 			if("roundabout".equals(way.getTag("junction")))
 				log.warn("Roundabout " + way.getId() + " has reverse oneway tag (" + way.getPoints().get(0).toOSMURL() + ")");
 		}
+		
+		addNodesForRestrictions(way);
 
 		if("roundabout".equals(way.getTag("junction"))) {
 			List<Coord> points = way.getPoints();
@@ -1020,6 +1024,81 @@
 		}
 	}
 
+	/**
+	 * Detect the case that two nodes are connected with 
+	 * different road segments and at least one node
+	 * is the via node of an "only-xxx" restriction.
+	 * If that is the case, make sure that there is
+	 * a node between them. If not, add it or change 
+	 * an existing point to a node by incrementing the highway
+	 * count.
+	 * Without this trick, only-restrictions might be ignored.
+	 * 
+	 * @param way the road
+	 */
+	private void addNodesForRestrictions(Way way) {
+		List<Coord> points = way.getPoints();
+		// loop downwards as we may add points
+		Coord lastNode = null;
+		int lastNodePos = -1;
+		for (int i = points.size() - 1; i >= 0; i--) {
+			Coord p1 = points.get(i);
+			if (p1.getHighwayCount() > 1){
+				if (lastNode != null){
+					if (lastNode.isViaNodeOfRestriction() && p1.isViaNodeOfRestriction()
+							|| (i == 0 && lastNodePos == points.size()-1 && (lastNode.isViaNodeOfRestriction() || p1.isViaNodeOfRestriction()))){
+						boolean addNode = false;
+						Coord[] testCoords = { p1, lastNode };
+						for (int k = 0; k < 2; k++){
+							if (testCoords[k].isViaNodeOfRestriction() == false)
+								continue;
+							List<RestrictionRelation> lrr = restrictions.get(testCoords[k]);
+							Coord test = k==0 ? testCoords[1]:testCoords[0];
+							for (RestrictionRelation rr : lrr) {
+								if (rr.isOnlyXXXRestriction() == false || rr.getFromWay() == way || rr.getToWay() == way)
+									continue;
+								// check if our way shares a point with either the to or from way
+								// we have to use Coord.equals() here because some
+								// points may already be CoordNodes while others are not
+								for (Coord co: rr.getToWay().getPoints()){
+									if (co.equals(test)){
+										addNode = true;
+										break;
+									}
+								}
+								for (Coord co: rr.getFromWay().getPoints()){
+									if (co.equals(test)){
+										addNode = true;
+										break;
+									}
+								}
+							}
+						}
+						if (addNode == false)
+							continue;
+						Coord co = null;
+						if (lastNodePos-i == 1){
+							if (p1.distance(lastNode) > 2 * minimumArcLength){
+								// create new point
+								co = lastNode.makeBetweenPoint(p1, 0.5);
+								co.incHighwayCount();
+								log.info("adding node in way ", way.toBrowseURL(), " to have node between two via points at " , co.toOSMURL());
+								points.add(lastNodePos,co);
+							}
+						} else {
+							co = points.get(i+1);
+							log.info("changing point to node in way " , way.toBrowseURL() , " to have node between two via points at " , co.toOSMURL());
+						}
+						if (co != null)
+							co.incHighwayCount();
+					}
+				}
+				lastNode = p1;
+				lastNodePos = i;
+			}
+		}
+	}
+
 	private void addRoadAfterSplittingLoops(Way way, GType gt) {
 		// make sure the way has nodes at each end
 		way.getPoints().get(0).incHighwayCount();
@@ -1513,8 +1592,11 @@
 						}
 					}
 				}
-
-				List<RestrictionRelation> theseRestrictions = restrictions.get(coord);
+				List<RestrictionRelation> theseRestrictions;
+				if (coord.isViaNodeOfRestriction())
+					theseRestrictions = restrictions.get(coord);
+				else
+					theseRestrictions = null;
 				if(theseRestrictions != null) {
 					// this node is the location of one or more
 					// restrictions
@@ -1523,7 +1605,7 @@
 						if(rr.getToWay().getId() == way.getId()) {
 							if(lastCoordNode != null)
 								rr.setToNode(lastCoordNode);
-						}
+							}
 						else if(rr.getFromWay().getId() == way.getId()) {
 							if(lastCoordNode != null)
 								rr.setFromNode(lastCoordNode);
@@ -1530,9 +1612,9 @@
 						}
 						else if(lastCoordNode != null) {
 							rr.addOtherNode(lastCoordNode);
-						}
 					}
 				}
+				}
 
 				lastRestrictions = theseRestrictions;
 				lastCoordNode = thisCoordNode;
@@ -2084,10 +2166,14 @@
 
 					// do the merge
 					++numNodesMerged;
-					if (p.getOnBoundary()) {
-						// current point is a boundary node so we need
+					if (p.getOnBoundary() || p.isViaNodeOfRestriction() && previousNode.getOnBoundary() == false) {
+						// current point is a boundary node or part of 
+						// a restriction relation so we need
 						// to merge the previous node into this node
 						replacements.put(previousNode, p);
+						if (previousNode.isViaNodeOfRestriction())
+							log.warn("via point is replaced at " + previousNode.toOSMURL());
+
 						previousNode.setReplaced(true);
 						p.setTreatAsNode(true);
 						// remove the preceding point(s) back to and
@@ -2099,6 +2185,8 @@
 						// current point is not on a boundary so merge
 						// this node into the previous one
 						replacements.put(p, previousNode);
+						if (p.isViaNodeOfRestriction())
+							log.warn("via point is replaced at " + p.toOSMURL());
 						p.setReplaced(true);
 						previousNode.setTreatAsNode(true);
 						// reset previous point to be the previous
Index: uk/me/parabola/mkgmap/reader/osm/RestrictionRelation.java
===================================================================
--- uk/me/parabola/mkgmap/reader/osm/RestrictionRelation.java	(revision 2889)
+++ uk/me/parabola/mkgmap/reader/osm/RestrictionRelation.java	(working copy)
@@ -292,13 +292,17 @@
 			if(restriction.startsWith("only_turn"))
 				log.warn(messagePrefix + "has bad type '" + restriction + "' it should be of the form only_X_turn rather than only_turn_X - I added the restriction anyway - allows routing to way " + toWay.toBrowseURL());
 			log.info(messagePrefix + restriction + " added - allows routing to way " + toWay.toBrowseURL());
-			HashSet<CoordNode> otherNodesUnique = new HashSet<CoordNode>(otherNodes);	
+			HashSet<CoordNode> otherNodesUnique = new HashSet<CoordNode>(otherNodes);
+			boolean wasUsed = false;
 			for(CoordNode otherNode : otherNodesUnique) {
-				if (!otherNode.equals(fromNode) && !otherNode.equals(toNode)) {
+				if (otherNode.getId() != fromNode.getId() && otherNode.getId() != toNode.getId()) {
 					log.info(messagePrefix + restriction + "  blocks routing to node " + otherNode.toOSMURL());
 					collector.addRestriction(fromNode, otherNode, viaNode, exceptMask);
+					wasUsed = true;
 				}
 			}
+			if (!wasUsed)
+				log.error(messagePrefix + restriction + " was ignored because from or via was identical to calculated to node"); 
 		}
 		else {
 			log.warn(messagePrefix + "has unsupported type '" + restriction + "'");
@@ -314,4 +318,8 @@
 	public String toString() {
 		return "[restriction = " + restriction + ", from = " + fromWay.toBrowseURL() + ", to = " + toWay.toBrowseURL() + ", via = " + viaCoord.toOSMURL() + "]";
 	}
+	
+	public boolean isOnlyXXXRestriction(){
+		return restriction.startsWith("only");
+	}
 }
