Index: src/uk/me/parabola/imgfmt/app/Coord.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/Coord.java	(revision 2793)
+++ src/uk/me/parabola/imgfmt/app/Coord.java	(working copy)
@@ -40,8 +40,8 @@
 	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 int latitude;
-	private final int longitude;
+	private int latitude;
+	private int longitude;
 	private byte highwayCount; // number of highways that use this point
 	private byte flags; // further attributes
 
@@ -302,4 +302,8 @@
 		return toOSMURL(17);
 	}
 
+	public void moveTo(int lat, int lon){
+		this.latitude = lat;
+		this.longitude = lon;
+	}
 }
Index: src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java	(revision 2793)
+++ src/uk/me/parabola/mkgmap/osmstyle/StyledConverter.java	(working copy)
@@ -27,6 +27,7 @@
 import java.util.logging.Level;
 import java.util.regex.Pattern;
 
+import uk.me.parabola.imgfmt.Utils;
 import uk.me.parabola.imgfmt.app.Area;
 import uk.me.parabola.imgfmt.app.Coord;
 import uk.me.parabola.imgfmt.app.CoordNode;
@@ -64,6 +65,7 @@
 import uk.me.parabola.mkgmap.reader.osm.Style;
 import uk.me.parabola.mkgmap.reader.osm.TypeResult;
 import uk.me.parabola.mkgmap.reader.osm.Way;
+import uk.me.parabola.util.GpxCreator;
 
 /**
  * Convert from OSM to the mkgmap intermediate format using a style.
@@ -110,6 +112,7 @@
 	private List<GType> lineTypes = new ArrayList<GType>();
 	private HashMap<Long, Way> modifiedRoads = new HashMap<Long, Way>();
 	private HashSet<Long> deletedRoads = new HashSet<Long>();
+	private String gpxPath;
 
 	private final double minimumArcLength;
 	
@@ -197,6 +200,8 @@
 					" This is no longer recommended for a routable map.");
 		}
 		linkPOIsToWays = props.getProperty("link-pois-to-ways") != null;
+		gpxPath = props.getProperty("gpx-dir", null);
+
 	}
 
 	/**
@@ -338,7 +343,9 @@
 		setHighwayCounts();
 		findUnconnectedRoads();
 		filterCoordPOI();
+		frigRoundabouts();
 		removeShortArcsByMergingNodes();
+		
 		// make sure that copies of modified roads are have equal points 
 		for (int i = 0; i < lines.size(); i++){
 			Way line = lines.get(i);
@@ -353,8 +360,8 @@
 				points.addAll(modWay.getPoints());
 			}
 		}
+		modifiedRoads = null;
 		deletedRoads = null;
-		modifiedRoads = null;
 
 		for (int i = 0; i < lines.size(); i++){
 			Way line = lines.get(i);
@@ -437,6 +444,94 @@
 	}
 
 	/**
+	 * Detect wrong angles in roundabouts caused by rounding to
+	 * map units. Try to move or remove points to frig it.
+	 *   
+	 */
+	private void frigRoundabouts() {
+		for (Way way: roads){
+			if (way == null)
+				continue;
+			if("roundabout".equals(way.getTag("junction")) == false) 
+				continue;
+			if (way.isClosed() == false || way.isComplete() == false)
+				continue;
+			
+			List<Coord> points = way.getPoints();
+			int n = points.size();
+			if (n  <= 4 )
+				continue;
+			
+			final int numSides = n - 1;
+			final double sumOfAngles = (numSides - 2) * 180;// for a regular polygon
+			final double niceAngle = sumOfAngles / numSides - 180; 
+			if (gpxPath != null)
+				GpxCreator.createGpx(gpxPath + way.getId() + "_o", points);
+			boolean changed = false;
+			for (int i = 1; i < points.size() ; i++) {
+				Coord p = points.get(i);
+				if (p.getOnBoundary())
+					continue;
+				Coord pPrev = points.get(i-1);
+				Coord pNext = (i+1 < points.size()) ? points.get(i+1):points.get(0);
+				
+				long angle = Math.round(Utils.getAngle(pPrev, p, pNext));
+				if (Math.abs(angle - niceAngle) > Math.abs(niceAngle)){
+//					System.out.println(way.getId() + " at " + i + " : " + angle + "°, preferred angle is " + niceAngle + ", diff: " + Math.abs(angle - niceAngle));
+					System.out.println("way " + way.getId() + ": bad angle " + angle + "° in roundabout at point " + p.toOSMURL());
+					double bestDeltaAngle = 1000;
+					Coord pBest = null;
+					int lat = p.getLatitude();
+					int lon = p.getLongitude();
+					// brute force: try all 8 coordinates close to the point (fast enough)
+					for (int x = -1; x <= 1; x++){
+						for (int y = -1; y <= 1; y++){
+							Coord pTest = new Coord(lat+y,lon+x);
+							if (p.equals(pTest) || pPrev.equals(pTest) || pNext.equals(pTest))
+								continue;
+							double testAngle = Utils.getAngle(pPrev, pTest, pNext);
+							double deltaAngle = Math.abs(testAngle-niceAngle);
+							if (deltaAngle < bestDeltaAngle){
+								pBest = pTest;
+								bestDeltaAngle = deltaAngle;
+							}
+						}
+					}
+					
+					// try also what happens if we remove the point
+					// TODO: Code to remove last point if needed
+					if (p.isTreatAsNode() == false){
+						if (i+2 < points.size()){
+							double delAngle = Utils.getAngle(pPrev, pNext, points.get(i+2));
+							double deltaAngleRemove = Math.abs(delAngle-niceAngle);
+							if (deltaAngleRemove < bestDeltaAngle || pBest == null && deltaAngleRemove < 30 ){
+								System.out.println("way " + way.getId() + ": removing point to smooth roundabout");
+								points.remove(i);
+								modifiedRoads.put(way.getId(), way);
+								changed = true;
+								i--;
+								continue;
+							}
+						}
+					}
+
+					if (pBest != null){
+						System.out.println("way " + way.getId() + ": moving point from " + p.toDegreeString() + " to " + pBest.toDegreeString() + " to smooth roundabout");
+						p.moveTo(pBest.getLatitude(), pBest.getLongitude());
+						changed = true;
+					} else {
+						System.out.println("way " + way.getId() + "cannot frig roundabout at this position.");
+					}
+				}
+			}
+			if (changed){
+				if (gpxPath != null)
+					GpxCreator.createGpx(gpxPath + way.getId() + "_m", points);
+			}
+		}
+	}
+
+	/**
 	 * Run the rules for this relation.  As this is not an end object, then
 	 * the only useful rules are action rules that set tags on the contained
 	 * ways or nodes.  Every rule should probably start with 'type=".."'.
