Index: src/uk/me/parabola/splitter/args/SplitterParams.java
===================================================================
--- src/uk/me/parabola/splitter/args/SplitterParams.java	(revision 321)
+++ src/uk/me/parabola/splitter/args/SplitterParams.java	(working copy)
@@ -40,6 +40,10 @@
 			+ "Nodes added by overlap or keep-complete are not taken into account.")
 	int getMaxNodes();
 
+	@Option(description = "A target value that is used when no split-file is given. Splitting is done so that "
+			+ "the given number of tiles is produced. The max-nodes value is ignored if this option is given.")
+	String getNumTiles();
+
 	@Option(defaultValue = "13", description = "The resolution of the overview map to be produced by mkgmap.")
 	int getResolution();
 
Index: src/uk/me/parabola/splitter/Main.java
===================================================================
--- src/uk/me/parabola/splitter/Main.java	(revision 321)
+++ src/uk/me/parabola/splitter/Main.java	(working copy)
@@ -85,6 +85,8 @@
 	// Nodes added by overlap or keep-complete are not taken into account. 
 	private long maxNodes;
 
+	private int numTiles = -1;
+	
 	// This is a value in the range 0-24.
 	// Higher numbers mean higher detail. The resolution determines how the tiles must
 	// be aligned. Eg a resolution of 13 means the tiles need to have their edges aligned to
@@ -335,6 +337,20 @@
 			System.err.println("The --mapid parameter must have less than 9 digits. Resetting to " + mapId + ".");
 		} 		
 		maxNodes = params.getMaxNodes();
+		String numTilesParm = params.getNumTiles();
+		if (numTilesParm != null){
+			try{
+				numTiles = Integer.parseInt(numTilesParm);
+				if (numTiles >= 0 && numTiles < 2 ){
+					System.err.println("Error: The --num-tiles parameter must be 2 or higher. Resetting to 2.");
+					numTiles = 2;
+				}
+			} catch(NumberFormatException e){
+				System.err.println("Error: Invalid number "+ numTilesParm + 
+						". The --num-tiles parameter must be an integer value of 2 or higher.");
+				System.exit(-1);
+			}
+		}
 		description = params.getDescription();
 		geoNamesFile = params.getGeonamesFile();
 		if (geoNamesFile != null){
@@ -522,12 +538,20 @@
 			return new AreaList(new ArrayList<Area>());
 		System.out.println("Exact map coverage is " + exactArea);
 		System.out.println("Rounded map coverage is " + splittableArea.getBounds());
-		System.out.println("Splitting nodes into areas containing a maximum of " + Utils.format(maxNodes) + " nodes each...");
+		
+		
 		splittableArea.setTrim(trim);
 		splittableArea.setMapId(mapId);
 		long startSplit = System.currentTimeMillis();
-		
-		List<Area> areas = splittableArea.split(maxNodes, polygon);
+		List<Area> areas ;
+		if (numTiles >= 2){
+			System.out.println("Splitting nodes into " + numTiles + " areas");
+			areas = splittableArea.split(maxNodes, polygon, numTiles);
+		}
+		else {
+			System.out.println("Splitting nodes into areas containing a maximum of " + Utils.format(maxNodes) + " nodes each...");
+			areas = splittableArea.split(maxNodes, polygon);
+		}
 		if (areas != null && areas.isEmpty() == false)
 			System.out.println("Creating the initial areas took " + (System.currentTimeMillis()- startSplit) + " ms");
 		return new AreaList(areas);
Index: src/uk/me/parabola/splitter/SplittableDensityArea.java
===================================================================
--- src/uk/me/parabola/splitter/SplittableDensityArea.java	(revision 321)
+++ src/uk/me/parabola/splitter/SplittableDensityArea.java	(working copy)
@@ -46,6 +46,7 @@
 	int minAspectRatioFactorPos = Integer.MAX_VALUE;
 	double maxAspectRatioFactor = Double.MIN_VALUE;
 	
+	private boolean beQuiet = false;
 	private long maxNodes;
 	private final int shift;
 	private HashSet<Tile> cache;
@@ -107,7 +108,8 @@
 		if (startSolution != null && startSolution.isNice())
 			return startSolution.getAreas(null);
 
-		System.out.println("Split was not yet succesfull. Trying to remove large empty areas...");
+		if (!beQuiet)
+			System.out.println("Split was not yet succesfull. Trying to remove large empty areas...");
 		List<Tile> startTiles = checkForEmptyClusters(0, startTile, true);
 		if (startTiles.size() == 1){
 			Tile tile = startTiles.get(0);
@@ -119,15 +121,18 @@
 					return startSolution.getAreas(null);
 			}
 		}			
-		System.out.println("Trying again with " + startTiles.size() + " trimmed partition(s), also allowing big empty parts.");
+		if (!beQuiet)
+			System.out.println("Trying again with " + startTiles.size() + " trimmed partition(s), also allowing big empty parts.");
 		allowEmptyPart = true;
 		for (Tile tile: startTiles){
-			System.out.println("Solving partition " + tile.toString());
+			if (!beQuiet)
+				System.out.println("Solving partition " + tile.toString());
 			Solution solution = solveRectangularArea(tile);
 			if (solution != null && solution.isEmpty() == false)
 				fullSolution.merge(solution);
 			else {
-				System.out.println("Warning: No solution found for partition " + tile.toString());
+				if (!beQuiet)
+					System.out.println("Warning: No solution found for partition " + tile.toString());
 			}
 		}
 		System.out.println("Final solution has " +  fullSolution.toString());
@@ -162,6 +167,61 @@
 	}
 
 	
+	public List<Area> split(long startMaxNodes, java.awt.geom.Area polygonArea, int wantedTiles) {
+		long currMaxNodes = this.allDensities.getNodeCount() / wantedTiles;
+		class Pair {
+			long maxNodes;
+			int numTiles;
+			
+			Pair(long maxNodes, int numTiles){
+				this.maxNodes = maxNodes;
+				this.numTiles = numTiles;  
+			}
+		}
+		Pair bestBelow = null;
+		Pair bestAbove = null;
+		beQuiet = true;
+		while (true) {
+			System.out.println("Trying a max-nodes value of " + currMaxNodes + " to split " + allDensities.getNodeCount() + " nodes into " + wantedTiles + " areas");
+			List<Area> res = split(currMaxNodes, polygonArea);
+			if (res.isEmpty() || res.size() == wantedTiles){
+				beQuiet = false;
+				res = split(currMaxNodes, polygonArea);
+				return res;
+			}
+			else {
+				Pair pair = new Pair(currMaxNodes, res.size());
+				if (res.size() > wantedTiles){
+					if (bestAbove == null)
+						bestAbove = pair;
+					else if (bestAbove.numTiles > pair.numTiles)
+						bestAbove = pair;
+					else  if (bestAbove.numTiles == pair.numTiles && pair.maxNodes < bestAbove.maxNodes)
+						bestAbove = pair;
+				} else {
+					if (bestBelow == null)
+						bestBelow = pair;
+					else if (bestBelow.numTiles < pair.numTiles)
+						bestBelow = pair;
+					else  if (bestBelow.numTiles == pair.numTiles && pair.maxNodes > bestBelow.maxNodes)
+						bestBelow = pair;
+				}
+				long testMaxNodes;
+				if (bestBelow == null || bestAbove == null)
+					testMaxNodes = Math.round((double) currMaxNodes * res.size() / wantedTiles);
+				else 
+					testMaxNodes = (bestBelow.maxNodes + bestAbove.maxNodes) / 2;
+				
+				if (testMaxNodes == currMaxNodes){
+					System.err.println("Cannot find split with exactly " + wantedTiles + " areas");
+					return res;
+				}
+				currMaxNodes = testMaxNodes;
+			}
+		} 
+	}
+
+	
 	/** 
 	 * Filter the density data, calculate once complex trigonometric results 
 	 * @param polygonArea
@@ -207,7 +267,8 @@
 				}
 			}
 		}
-		System.out.println("Highest node count in a single grid element is " +Utils.format(maxNodesInDensityMapGridElement));
+		if (!beQuiet)
+			System.out.println("Highest node count in a single grid element is " +Utils.format(maxNodesInDensityMapGridElement));
 		yxMap = new int [height][width];
 		for(int y = 0; y < height; y++){
 			for (int x = 0; x < width; x++){
@@ -572,7 +633,8 @@
 		spread = 0;
 		minNodes = 0;
 		maxAspectRatio = 1L<<allDensities.getShift();
-		System.out.println("Trying to find nice split for " + startTile);
+		if (!beQuiet)
+			System.out.println("Trying to find nice split for " + startTile);
 		Solution bestSolution = new Solution();
 		for (int numLoops = 0; numLoops < MAX_LOOPS; numLoops++){
 			double saveMaxAspectRatio = maxAspectRatio; 
@@ -586,7 +648,8 @@
 					foundBetter = true;
 					System.out.println("Best solution until now: " + bestSolution.toString());
 					if (bestSolution.isNice()){
-						System.out.println("This seems to be nice.");
+						if (!beQuiet)
+							System.out.println("This seems to be nice.");
 						break;
 					}
 				}
@@ -1111,13 +1174,15 @@
 						fits = false;
 				}
 				Area area = new Area(r.y,r.x,(int)r.getMaxY(),(int)r.getMaxX());
-				if (tile.count > maxNodes)
-					note = " but is already at the minimum size so can't be split further";
-				else
-					note = "";
-				long percentage = 100 * tile.count / maxNodes;
-				System.out.println("Area " + num++ + " covers " + area 
-						+ " and contains " + tile.count + " nodes (" + percentage + " %)" + note);
+				if (!beQuiet){
+					if (tile.count > maxNodes)
+						note = " but is already at the minimum size so can't be split further";
+					else
+						note = "";
+					long percentage = 100 * tile.count / maxNodes;
+					System.out.println("Area " + num++ + " covers " + area 
+							+ " and contains " + tile.count + " nodes (" + percentage + " %)" + note);
+				}
 				result.add(area);
 			}
 			if (fits == false){
