diff --git a/src/uk/me/parabola/imgfmt/app/net/RoadDef.java b/src/uk/me/parabola/imgfmt/app/net/RoadDef.java
index b5ad5d9..2f7beb3 100644
--- a/src/uk/me/parabola/imgfmt/app/net/RoadDef.java
+++ b/src/uk/me/parabola/imgfmt/app/net/RoadDef.java
@@ -72,6 +72,10 @@ public class RoadDef implements Comparable {
 		return "RoadDef(" + name + ", " + roadId + ")";
 	}
 
+	public String getName() {
+		return name;
+	}
+
 	/*
 	 * Everything that's relevant for writing to NET1.
 	 */
diff --git a/src/uk/me/parabola/imgfmt/app/net/RouteArc.java b/src/uk/me/parabola/imgfmt/app/net/RouteArc.java
index 7405fa7..21fc11d 100644
--- a/src/uk/me/parabola/imgfmt/app/net/RouteArc.java
+++ b/src/uk/me/parabola/imgfmt/app/net/RouteArc.java
@@ -258,7 +258,7 @@ public class RouteArc {
 		// now, 14 bits for length
 		assert !curve : "not writing curve data yet";
 		if (length >= (1 << 14)) {
-			log.warn("length too large:", length, "(truncating)");
+			log.error("Way " + roadDef.getName() + " contains an arc whose length is too big to be encoded so the road will not be routable");
 			length = (1 << 14) - 1;
 		}
 
diff --git a/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java b/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
index 99ab26a..69e023a 100644
--- a/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
+++ b/src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
@@ -79,6 +79,8 @@ public class StyledConverter implements OsmConverter {
 
 	private int roadId;
 
+	private final int MAX_ARC_LENGTH = (1 << 14) - 1;
+
 	private final int MAX_POINTS_IN_WAY = 200;
 
 	private final int MAX_NODES_IN_WAY = 16;
@@ -434,7 +436,7 @@ public class StyledConverter implements OsmConverter {
 				clippedWays = new ArrayList<Way>();
 
 				for (List<Coord> lco : lineSegs) {
-					Way nWay = new Way();
+					Way nWay = new Way(way.getId());
 					nWay.setName(way.getName());
 					nWay.copyTags(way);
 					for(Coord co : lco) {
@@ -525,21 +527,55 @@ public class StyledConverter implements OsmConverter {
 		}
 	}
 
+	String getDebugName(Way way) {
+		String name = way.getName();
+		if(name == null)
+			name = way.getTag("ref");
+		if(name == null)
+			name = "";
+		return name + " (OSM id " + way.getId() + ")";
+	}
+
 	void addRoadWithoutLoops(Way way, GType gt) {
 		List<Integer> nodeIndices = new ArrayList<Integer>();
 		List<Coord> points = way.getPoints();
 		Way trailingWay = null;
-		String wayName = way.getName();
+		String debugWayName = getDebugName(way);
 
 		// make sure the way has nodes at each end
 		points.get(0).incHighwayCount();
 		points.get(points.size() - 1).incHighwayCount();
 
-		// collect the Way's nodes
+		// collect the Way's nodes and also split the way if any
+		// inter-node arc length becomes excessive
+		double arcLength = 0;
 		for(int i = 0; i < points.size(); ++i) {
 			Coord p = points.get(i);
-			int highwayCount = p.getHighwayCount();
-			if(highwayCount > 1) {
+
+			// check if we should split the way at this point to limit
+			// the arc length between nodes
+			if((i + 1) < points.size()) {
+				double d = p.distance(points.get(i + 1));
+				if(d > MAX_ARC_LENGTH) {
+					log.error("Way " + debugWayName + " contains a segment that is longer than " + MAX_ARC_LENGTH + " (routing will fail for that way)");
+				}
+				else if((arcLength + d) > MAX_ARC_LENGTH) {
+					assert i > 0;
+					trailingWay = splitWayAt(way, i);
+					// this will have truncated the current Way's
+					// points so the loop will now terminate
+					log.warn("Splitting way " + debugWayName + " at " + points.get(i).toDegreeString() + " to limit arc length to " + (long)arcLength);
+				}
+				else {
+					if(p.getHighwayCount() > 1)
+						// point is a node so zero arc length
+						arcLength = 0;
+
+					arcLength += d;
+				}
+			}
+
+			if(p.getHighwayCount() > 1) {
 				// this point is a node connecting highways
 				Integer nodeId = nodeIdMap.get(p);
 				if(nodeId == null) {
@@ -556,7 +592,7 @@ public class StyledConverter implements OsmConverter {
 					trailingWay = splitWayAt(way, i);
 					// this will have truncated the current Way's
 					// points so the loop will now terminate
-					log.info("Splitting way " + wayName + " at " + points.get(i).toDegreeString() + " as it has at least " + MAX_NODES_IN_WAY + " nodes");
+					log.info("Splitting way " + debugWayName + " at " + points.get(i).toDegreeString() + " as it has at least " + MAX_NODES_IN_WAY + " nodes");
 				}
 			}
 		}
@@ -609,7 +645,7 @@ public class StyledConverter implements OsmConverter {
 					// access
 					noAccess[index] = true;
 				}
-				log.info(type + " is not allowed in " + highwayType + " " + wayName);
+				log.info(type + " is not allowed in " + highwayType + " " + debugWayName);
 			} else if (accessExplicitlyAllowed(accessTagValue)) {
 				if (index == RoadNetwork.NO_MAX) {
 					// everything is allowed access
@@ -620,22 +656,22 @@ public class StyledConverter implements OsmConverter {
 					// access
 					noAccess[index] = false;
 				}
-				log.info(type + " is allowed in " + highwayType + " " + wayName);
+				log.info(type + " is allowed in " + highwayType + " " + debugWayName);
 			}
 			else if (accessTagValue.equalsIgnoreCase("destination")) {
 				if (type.equals("motorcar") ||
 				    type.equals("motorcycle")) {
 					road.setNoThroughRouting();
 				} else if (type.equals("access")) {
-					log.warn("access=destination only affects routing for cars in " + highwayType + " " + wayName);
+					log.warn("access=destination only affects routing for cars in " + highwayType + " " + debugWayName);
 					road.setNoThroughRouting();
 				} else {
-					log.warn(type + "=destination ignored in " + highwayType + " " + wayName);
+					log.warn(type + "=destination ignored in " + highwayType + " " + debugWayName);
 				}
 			} else if (accessTagValue.equalsIgnoreCase("unknown")) {
 				// implicitly allow access
 			} else {
-				log.warn("Ignoring unsupported access tag value " + type + "=" + accessTagValue + " in " + highwayType + " " + wayName);
+				log.warn("Ignoring unsupported access tag value " + type + "=" + accessTagValue + " in " + highwayType + " " + debugWayName);
 			}
 		}
 
@@ -672,7 +708,7 @@ public class StyledConverter implements OsmConverter {
 				Integer nodeId = nodeIdMap.get(coord);
 				boolean boundary = boundaryCoords.contains(coord);
 				if(boundary) {
-					log.info("Way " + wayName + "'s point #" + n + " at " + points.get(n).toDegreeString() + " is a boundary node");
+					log.info("Way " + debugWayName + "'s point #" + n + " at " + points.get(n).toDegreeString() + " is a boundary node");
 				}
 
 				CoordNode thisCoordNode = new CoordNode(coord.getLatitude(), coord.getLongitude(), nodeId, boundary);
@@ -735,7 +771,7 @@ public class StyledConverter implements OsmConverter {
 	// original Way is truncated)
 
 	Way splitWayAt(Way way, int index) {
-		Way trailingWay = new Way();
+		Way trailingWay = new Way(way.getId());
 		List<Coord> wayPoints = way.getPoints();
 		int numPointsInWay = wayPoints.size();
 
diff --git a/src/uk/me/parabola/mkgmap/reader/osm/Way.java b/src/uk/me/parabola/mkgmap/reader/osm/Way.java
index 78757c3..f1aa624 100644
--- a/src/uk/me/parabola/mkgmap/reader/osm/Way.java
+++ b/src/uk/me/parabola/mkgmap/reader/osm/Way.java
@@ -32,6 +32,10 @@ public class Way extends Element {
 
 	private final List<Coord> points = new ArrayList<Coord>();
 
+	public Way(long id) {
+		setId(id);
+	}
+
 	/**
 	 * Get the points that make up the way.  We attempt to re-order the segments
 	 * and return a list of points that traces the route of the way.
diff --git a/src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java b/src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java
index cae89c3..0dfb758 100644
--- a/src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java
+++ b/src/uk/me/parabola/mkgmap/reader/osm/xml/Osm5XmlHandler.java
@@ -444,8 +444,8 @@ class Osm5XmlHandler extends DefaultHandler {
 
 	private void addWay(String sid) {
 		try {
-			currentWay = new Way();
 			long id = idVal(sid);
+			currentWay = new Way(id);
 			wayMap.put(id, currentWay);
 		} catch (NumberFormatException e) {
 			// ignore bad numeric data.
