Index: src/uk/me/parabola/mkgmap/build/MapArea.java
===================================================================
--- src/uk/me/parabola/mkgmap/build/MapArea.java	(revision 4685)
+++ src/uk/me/parabola/mkgmap/build/MapArea.java	(working copy)
@@ -257,14 +257,16 @@
 					continue;
 				}
 				int areaIndex = pickArea(mapAreas, e, xbaseHp, ybaseHp, nx, ny, dxHp, dyHp);
-				if ((shapeBounds.getHeight() > maxHeight || shapeBounds.getWidth() > maxWidth) &&
-				    !areas[areaIndex].contains(shapeBounds)) {
+				if (areas[areaIndex].contains(shapeBounds)) {
+					mapAreas[areaIndex].addShape(e);
+				} else if (shapeBounds.getHeight() <= maxHeight && shapeBounds.getWidth() <= maxWidth) {
+					// this polygon is partially outside the subdivision, but won't exceed the allowable offsets
+					mapAreas[areaIndex].addShape(e);
+				} else {
 					MapArea largeObjectArea = new MapArea(shapeBounds, areaResolution, true); // use splitIntoAreas to deal with overflow
 					largeObjectArea.addShape(e);
 					addedAreas.add(largeObjectArea);
-					continue;
 				}
-				mapAreas[areaIndex].addShape(e);
 			}
 		}
 
Index: src/uk/me/parabola/mkgmap/build/MapBuilder.java
===================================================================
--- src/uk/me/parabola/mkgmap/build/MapBuilder.java	(revision 4685)
+++ src/uk/me/parabola/mkgmap/build/MapBuilder.java	(working copy)
@@ -803,11 +803,15 @@
 			List<SourceSubdiv> nextList = new ArrayList<>();
 
 			Zoom zoom = map.createZoom(linfo.getLevel(), linfo.getBits());
+			//%%%mbs see also MapSpltter.split()
+			// method 1: true at levels > 0, depends on --order-by for level 9
+			// method 2: depends on --order-by for all levels
+			boolean splitPolygonsIntoArea = /* linfo.getLevel() != 0 ? true : */ orderByDecreasingArea;
 
 			for (SourceSubdiv srcDivPair : srcList) {
 
 				MapSplitter splitter = new MapSplitter(srcDivPair.getSource(), zoom);
-				MapArea[] areas = splitter.split(orderByDecreasingArea);
+				MapArea[] areas = splitter.split(splitPolygonsIntoArea);
 				log.info("Map region", srcDivPair.getSource().getBounds(), "split into", areas.length, "areas at resolution", zoom.getResolution());
 
 				for (MapArea area : areas) {
Index: src/uk/me/parabola/mkgmap/build/MapSplitter.java
===================================================================
--- src/uk/me/parabola/mkgmap/build/MapSplitter.java	(revision 4685)
+++ src/uk/me/parabola/mkgmap/build/MapSplitter.java	(working copy)
@@ -91,16 +91,19 @@
 	 *
 	 * This routine is not called recursively.
 	 *
-	 * @param orderByDecreasingArea aligns subareas as powerOf2 and splits polygons into the subareas.  
+	 * @param splitPolygonsIntoArea aligns subareas as powerOf2 and splits polygons into the subareas.  
 	 * @return An array of map areas, each of which is within the size limit
 	 * and the limit on the number of features.
 	 */
-	public MapArea[] split(boolean orderByDecreasingArea) {
+	public MapArea[] split(boolean splitPolygonsIntoArea) {
 		log.debug("orig area", mapSource.getBounds());
 
-		MapArea ma = initialArea(mapSource, orderByDecreasingArea);
+		MapArea ma = initialArea(mapSource, splitPolygonsIntoArea);
 		MapArea[] origArea = {ma};
-		MapArea[] areas = splitMaxSize(ma);
+		//%%%mbs see also MapBuilder.makeMapAreas()
+		// method 1: maybe always be true so that even at level 0, 0x4b polygons don't overlap?
+		// method 2: depends on incoming param
+		MapArea[] areas = splitMaxSize(ma, /* true */ splitPolygonsIntoArea);
 		if (areas == null) {
 			log.warn("initial split returned null for", ma);
 			return origArea;
@@ -209,9 +212,10 @@
 	 * If the area is already small enough then it will be returned unchanged.
 	 *
 	 * @param mapArea The area that needs to be split down.
+	 * @param splitPolygonsIntoArea If true, don't expand subDiv due to oversize elements
 	 * @return An array of map areas.  Each will be below the max size.
 	 */
-	private MapArea[] splitMaxSize(MapArea mapArea) {
+	private MapArea[] splitMaxSize(MapArea mapArea, boolean splitPolygonsIntoArea) { //%%%mbs new param
 		/**
 		 * mapArea.getBounds() comes from the original map source or parent/split MapArea.
 		 * mapArea.getFullBounds() is calculated from elements added to the MapArea.
@@ -223,9 +227,16 @@
 		 * Some map sources might not set getBounds().
 		 * If there are no elements, getFullBounds isEmpty.
 		*/
-		Area bounds = mapArea.getBounds(); 
-		if (bounds.isEmpty()) // ??? think this func is wrong for single point/horiz/vert/line
-			bounds = mapArea.getFullBounds(); 
+		Area bounds;
+		if (splitPolygonsIntoArea) { // splitting based on parent/map size
+			bounds = mapArea.getBounds();
+			if (bounds.isEmpty()) // ??? think this func is wrong for single point/horiz/vert/line
+				bounds = mapArea.getFullBounds();
+		} else { // use bounds with any expansion due to oversize elements allowed into subdivisions
+			bounds = mapArea.getFullBounds();
+			if (bounds.isEmpty())
+				bounds = mapArea.getBounds();
+		}
 		if (bounds.isEmpty())
 			return null;
 
