Index: src/uk/me/parabola/imgfmt/app/BufferedImgFileWriter.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/BufferedImgFileWriter.java	(revision 4602)
+++ src/uk/me/parabola/imgfmt/app/BufferedImgFileWriter.java	(working copy)
@@ -20,7 +20,7 @@
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
-import uk.me.parabola.imgfmt.MapFailedException;
+import uk.me.parabola.imgfmt.MapTooBigException;
 import uk.me.parabola.imgfmt.Sized;
 import uk.me.parabola.imgfmt.fs.ImgChannel;
 import uk.me.parabola.imgfmt.sys.FileLink;
@@ -270,11 +270,7 @@
 			while(needed > (bufferSize - GUARD_SIZE))
 				bufferSize += GROW_SIZE;
 			if (bufferSize > maxAllowedSize) {
-				// Previous message was confusing people, although it is difficult to come
-				// up with something that is strictly true in all situations.
-				throw new MapFailedException(
-						"There is not enough room in a single garmin map for all the input data." +
-								" The .osm file should be split into smaller pieces first.");
+				throw new MapTooBigException(maxAllowedSize);
 			}
 			ByteBuffer newb = ByteBuffer.allocate(bufferSize);
 			newb.order(ByteOrder.LITTLE_ENDIAN);
Index: src/uk/me/parabola/imgfmt/MapFailedException.java
===================================================================
--- src/uk/me/parabola/imgfmt/MapFailedException.java	(revision 4602)
+++ src/uk/me/parabola/imgfmt/MapFailedException.java	(working copy)
@@ -12,8 +12,6 @@
  */
 package uk.me.parabola.imgfmt;
 
-import uk.me.parabola.log.Logger;
-
 /**
  * Used for cases where the current map has failed to compile, but the error
  * is expected to be specific to the map (eg it is too big etc).  When this
@@ -26,10 +24,10 @@
  * @author Steve Ratcliffe
  */
 public class MapFailedException extends RuntimeException {
-	private static final Logger log = Logger.getLogger(MapFailedException.class);
 
 	/**
-	 * Constructs a new runtime exception with the specified detail message.
+	 * Constructs a new runtime exception with the calling method name
+	 * appended to the detail message.
 	 * The cause is not initialized, and may subsequently be initialized by a
 	 * call to {@link #initCause}.
 	 *
@@ -37,13 +35,13 @@
 	 *                later retrieval by the {@link #getMessage()} method.
 	 */
 	public MapFailedException(String message) {
-		super(message);
-		log(message);
+		super(buildMessage(message));
 	}
 
 	/**
-	 * Constructs a new runtime exception with the specified detail message and
-	 * cause.  <p>Note that the detail message associated with
+	 * Constructs a new runtime exception with the calling method name
+	 * appended to the detail message and includes the cause.
+	 * <p>Note that the detail message associated with
 	 * <code>cause</code> is <i>not</i> automatically incorporated in
 	 * this runtime exception's detail message.
 	 *
@@ -53,23 +51,32 @@
 	 *                {@link #getCause()} method).  (A <tt>null</tt> value is
 	 *                permitted, and indicates that the cause is nonexistent or
 	 *                unknown.)
-	 * @since 1.4
 	 */
 	public MapFailedException(String message, Throwable cause) {
-		super(message, cause);
-		log(message);
+		super(buildMessage(message), cause);
 	}
 	
-	private static void log(String message){
+	/**
+	 * Constructs a new runtime exception without appending the calling method
+	 * name to the detail message. The calling method can be appended by the
+	 * derived class if required.
+	 */
+	protected MapFailedException(String message, boolean ignored) {
+		super(message);
+	}
+
+	/**
+	 * Appends the calling method name to the supplied message.
+	 */
+	protected static String buildMessage(String message) {
 		String thrownBy = "";
 		try{
 			StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
 			int callerPosInStack = 3; 
 			String[] caller = stackTraceElements[callerPosInStack].getClassName().split("\\.");
-			thrownBy = "(thrown in " + caller[caller.length-1]+ "." +stackTraceElements[callerPosInStack].getMethodName() + "()) ";
+			thrownBy = " (thrown in " + caller[caller.length-1]+ "." +stackTraceElements[callerPosInStack].getMethodName() + "())";
 		} catch(Exception e){
-			log.info(e);
 		}
-		log.error(thrownBy + message);
+		return message + thrownBy;
 	}
 }
\ No newline at end of file
Index: src/uk/me/parabola/imgfmt/MapTooBigException.java
===================================================================
--- src/uk/me/parabola/imgfmt/MapTooBigException.java	(nonexistent)
+++ src/uk/me/parabola/imgfmt/MapTooBigException.java	(working copy)
@@ -0,0 +1,21 @@
+package uk.me.parabola.imgfmt;
+
+public class MapTooBigException extends MapFailedException {
+	protected long maxAllowedSize;
+
+	public MapTooBigException(long maxSize) {
+		this(maxSize,
+				"The map or tile is too big.",
+				"Try splitting the map into smaller tiles or reducing the amount of information included in the map.");
+	}
+	
+	public MapTooBigException(long maxSize, String message, String suggestion) {
+		super(message + " The maximum size is " + maxSize + ". " + suggestion, false);
+		maxAllowedSize = maxSize;
+	}
+	
+	public long getMaxAllowedSize() {
+		return maxAllowedSize;
+	}
+
+}
Index: src/uk/me/parabola/mkgmap/combiners/OverviewBuilder.java
===================================================================
--- src/uk/me/parabola/mkgmap/combiners/OverviewBuilder.java	(revision 4602)
+++ src/uk/me/parabola/mkgmap/combiners/OverviewBuilder.java	(working copy)
@@ -22,6 +22,7 @@
 import uk.me.parabola.imgfmt.FileNotWritableException;
 import uk.me.parabola.imgfmt.FileSystemParam;
 import uk.me.parabola.imgfmt.MapFailedException;
+import uk.me.parabola.imgfmt.MapTooBigException;
 import uk.me.parabola.imgfmt.Utils;
 import uk.me.parabola.imgfmt.app.Area;
 import uk.me.parabola.imgfmt.app.Coord;
@@ -195,6 +196,10 @@
 			throw new ExitException("Could not create overview map", e);
 		} catch (FileNotWritableException e) {
 			throw new ExitException("Could not write to overview map", e);
+		} catch (MapTooBigException e) {
+			throw new MapTooBigException(e.getMaxAllowedSize(),
+					"The overview map is too big.",
+					"Try reducing the highest overview resolution or reducing the amount of information included in the overview.");
 		}
 	}
 
Index: src/uk/me/parabola/mkgmap/main/Main.java
===================================================================
--- src/uk/me/parabola/mkgmap/main/Main.java	(revision 4602)
+++ src/uk/me/parabola/mkgmap/main/Main.java	(working copy)
@@ -151,7 +151,7 @@
 				System.err.println("Try using the Java -Xmx option to increase the available heap memory.");
 		} catch (MapFailedException e) {
 			// one of the combiners failed
-			e.printStackTrace();
+			log.error(e.getMessage());
 			++numExitExceptions;
 		} catch (ExitException e) {
 			++numExitExceptions;
@@ -563,6 +563,7 @@
 				} catch (OutOfMemoryError | ExitException e) {
 					throw e;
 				} catch (MapFailedException mfe) {
+					log.error(mfe.getMessage());
 					numMapFailedExceptions++;
 					setProgramRC(-1);
 				} catch (Throwable t) {
